diff --git a/README.md b/README.md index f1393495d..c5017f8fa 100644 --- a/README.md +++ b/README.md @@ -149,11 +149,8 @@ Not sure where to get started? You can: - Join our Slack, and ask us any questions there. -## Resources +## We are hiring! -- [Docs](https://infisical.com/docs/documentation/getting-started/introduction) for comprehensive documentation and guides -- [Slack](https://infisical.com/slack) for discussion with the community and Infisical team. -- [GitHub](https://github.com/Infisical/infisical) for code, issues, and pull requests -- [Twitter](https://twitter.com/infisical) for fast news -- [YouTube](https://www.youtube.com/@infisical_os) for videos on secret management -- [Blog](https://infisical.com/blog) for secret management insights, articles, tutorials, and updates +If you're reading this, there is a strong chance you like the products we created. + +You might also make a great addition to our team. We're growing fast and would love for you to [join us](https://infisical.com/careers). diff --git a/backend/src/db/migrations/20250717195959_gatewayid-for-app-conn.ts b/backend/src/db/migrations/20250717195959_gatewayid-for-app-conn.ts new file mode 100644 index 000000000..531cdcae8 --- /dev/null +++ b/backend/src/db/migrations/20250717195959_gatewayid-for-app-conn.ts @@ -0,0 +1,19 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; + +export async function up(knex: Knex): Promise { + if (!(await knex.schema.hasColumn(TableName.AppConnection, "gatewayId"))) { + await knex.schema.alterTable(TableName.AppConnection, (t) => { + t.uuid("gatewayId").nullable(); + }); + } +} + +export async function down(knex: Knex): Promise { + if (await knex.schema.hasColumn(TableName.AppConnection, "gatewayId")) { + await knex.schema.alterTable(TableName.AppConnection, (t) => { + t.dropColumn("gatewayId"); + }); + } +} diff --git a/backend/src/db/migrations/20250718133527_project-unify-revert.ts b/backend/src/db/migrations/20250718133527_project-unify-revert.ts new file mode 100644 index 000000000..53f1be9e4 --- /dev/null +++ b/backend/src/db/migrations/20250718133527_project-unify-revert.ts @@ -0,0 +1,433 @@ +import slugify from "@sindresorhus/slugify"; +import { Knex } from "knex"; +import { v4 as uuidV4 } from "uuid"; + +import { alphaNumericNanoId } from "@app/lib/nanoid"; + +import { ProjectType, TableName } from "../schemas"; + +/* eslint-disable no-await-in-loop,@typescript-eslint/ban-ts-comment */ + +// Single query to get all projects that need any kind of kickout +const getProjectsNeedingKickouts = async ( + knex: Knex +): Promise< + Array<{ + id: string; + defaultProduct: string; + needsSecretManager: boolean; + needsCertManager: boolean; + needsSecretScanning: boolean; + needsKms: boolean; + needsSsh: boolean; + }> +> => { + const result = await knex.raw( + ` +SELECT DISTINCT + p.id, + p."defaultProduct", + + -- Use CASE with direct joins instead of EXISTS subqueries + CASE WHEN p."defaultProduct" != 'secret-manager' AND s.secret_exists IS NOT NULL THEN true ELSE false END AS "needsSecretManager", + CASE WHEN p."defaultProduct" != 'cert-manager' AND ca.ca_exists IS NOT NULL THEN true ELSE false END AS "needsCertManager", + CASE WHEN p."defaultProduct" != 'secret-scanning' AND ssds.ssds_exists IS NOT NULL THEN true ELSE false END AS "needsSecretScanning", + CASE WHEN p."defaultProduct" != 'kms' AND kk.kms_exists IS NOT NULL THEN true ELSE false END AS "needsKms", + CASE WHEN p."defaultProduct" != 'ssh' AND sc.ssh_exists IS NOT NULL THEN true ELSE false END AS "needsSsh" + +FROM projects p +LEFT JOIN ( + SELECT DISTINCT e."projectId", 1 as secret_exists + FROM secrets_v2 s + JOIN secret_folders sf ON sf.id = s."folderId" + JOIN project_environments e ON e.id = sf."envId" +) s ON s."projectId" = p.id AND p."defaultProduct" != 'secret-manager' + +LEFT JOIN ( + SELECT DISTINCT "projectId", 1 as ca_exists + FROM certificate_authorities +) ca ON ca."projectId" = p.id AND p."defaultProduct" != 'cert-manager' + +LEFT JOIN ( + SELECT DISTINCT "projectId", 1 as ssds_exists + FROM secret_scanning_data_sources +) ssds ON ssds."projectId" = p.id AND p."defaultProduct" != 'secret-scanning' + +LEFT JOIN ( + SELECT DISTINCT "projectId", 1 as kms_exists + FROM kms_keys + WHERE "isReserved" = false +) kk ON kk."projectId" = p.id AND p."defaultProduct" != 'kms' + +LEFT JOIN ( + SELECT DISTINCT sca."projectId", 1 as ssh_exists + FROM ssh_certificates sc + JOIN ssh_certificate_authorities sca ON sca.id = sc."sshCaId" +) sc ON sc."projectId" = p.id AND p."defaultProduct" != 'ssh' + +WHERE p."defaultProduct" IS NOT NULL + AND ( + (p."defaultProduct" != 'secret-manager' AND s.secret_exists IS NOT NULL) OR + (p."defaultProduct" != 'cert-manager' AND ca.ca_exists IS NOT NULL) OR + (p."defaultProduct" != 'secret-scanning' AND ssds.ssds_exists IS NOT NULL) OR + (p."defaultProduct" != 'kms' AND kk.kms_exists IS NOT NULL) OR + (p."defaultProduct" != 'ssh' AND sc.ssh_exists IS NOT NULL) + ) + ` + ); + + return result.rows; +}; + +const newProject = async (knex: Knex, projectId: string, projectType: ProjectType) => { + const newProjectId = uuidV4(); + const project = await knex(TableName.Project).where("id", projectId).first(); + await knex(TableName.Project).insert({ + ...project, + type: projectType, + defaultProduct: null, + // @ts-ignore id is required + id: newProjectId, + slug: slugify(`${project?.name}-${alphaNumericNanoId(8)}`) + }); + + const customRoleMapping: Record = {}; + const projectCustomRoles = await knex(TableName.ProjectRoles).where("projectId", projectId); + if (projectCustomRoles.length) { + await knex.batchInsert( + TableName.ProjectRoles, + projectCustomRoles.map((el) => { + const id = uuidV4(); + customRoleMapping[el.id] = id; + return { + ...el, + id, + projectId: newProjectId, + permissions: el.permissions ? JSON.stringify(el.permissions) : el.permissions + }; + }) + ); + } + const groupMembershipMapping: Record = {}; + const groupMemberships = await knex(TableName.GroupProjectMembership).where("projectId", projectId); + if (groupMemberships.length) { + await knex.batchInsert( + TableName.GroupProjectMembership, + groupMemberships.map((el) => { + const id = uuidV4(); + groupMembershipMapping[el.id] = id; + return { ...el, id, projectId: newProjectId }; + }) + ); + } + + const groupMembershipRoles = await knex(TableName.GroupProjectMembershipRole).whereIn( + "projectMembershipId", + groupMemberships.map((el) => el.id) + ); + if (groupMembershipRoles.length) { + await knex.batchInsert( + TableName.GroupProjectMembershipRole, + groupMembershipRoles.map((el) => { + const id = uuidV4(); + const projectMembershipId = groupMembershipMapping[el.projectMembershipId]; + const customRoleId = el.customRoleId ? customRoleMapping[el.customRoleId] : el.customRoleId; + return { ...el, id, projectMembershipId, customRoleId }; + }) + ); + } + + const identityProjectMembershipMapping: Record = {}; + const identities = await knex(TableName.IdentityProjectMembership).where("projectId", projectId); + if (identities.length) { + await knex.batchInsert( + TableName.IdentityProjectMembership, + identities.map((el) => { + const id = uuidV4(); + identityProjectMembershipMapping[el.id] = id; + return { ...el, id, projectId: newProjectId }; + }) + ); + } + + const identitiesRoles = await knex(TableName.IdentityProjectMembershipRole).whereIn( + "projectMembershipId", + identities.map((el) => el.id) + ); + if (identitiesRoles.length) { + await knex.batchInsert( + TableName.IdentityProjectMembershipRole, + identitiesRoles.map((el) => { + const id = uuidV4(); + const projectMembershipId = identityProjectMembershipMapping[el.projectMembershipId]; + const customRoleId = el.customRoleId ? customRoleMapping[el.customRoleId] : el.customRoleId; + return { ...el, id, projectMembershipId, customRoleId }; + }) + ); + } + + const projectMembershipMapping: Record = {}; + const projectUserMembers = await knex(TableName.ProjectMembership).where("projectId", projectId); + if (projectUserMembers.length) { + await knex.batchInsert( + TableName.ProjectMembership, + projectUserMembers.map((el) => { + const id = uuidV4(); + projectMembershipMapping[el.id] = id; + return { ...el, id, projectId: newProjectId }; + }) + ); + } + const membershipRoles = await knex(TableName.ProjectUserMembershipRole).whereIn( + "projectMembershipId", + projectUserMembers.map((el) => el.id) + ); + if (membershipRoles.length) { + await knex.batchInsert( + TableName.ProjectUserMembershipRole, + membershipRoles.map((el) => { + const id = uuidV4(); + const projectMembershipId = projectMembershipMapping[el.projectMembershipId]; + const customRoleId = el.customRoleId ? customRoleMapping[el.customRoleId] : el.customRoleId; + return { ...el, id, projectMembershipId, customRoleId }; + }) + ); + } + + const kmsKeys = await knex(TableName.KmsKey).where("projectId", projectId).andWhere("isReserved", true); + if (kmsKeys.length) { + await knex.batchInsert( + TableName.KmsKey, + kmsKeys.map((el) => { + const id = uuidV4(); + const slug = slugify(alphaNumericNanoId(8).toLowerCase()); + return { ...el, id, slug, projectId: newProjectId }; + }) + ); + } + + const projectBot = await knex(TableName.ProjectBot).where("projectId", projectId).first(); + if (projectBot) { + const newProjectBot = { ...projectBot, id: uuidV4(), projectId: newProjectId }; + await knex(TableName.ProjectBot).insert(newProjectBot); + } + + const projectKeys = await knex(TableName.ProjectKeys).where("projectId", projectId); + if (projectKeys.length) { + await knex.batchInsert( + TableName.ProjectKeys, + projectKeys.map((el) => { + const id = uuidV4(); + return { ...el, id, projectId: newProjectId }; + }) + ); + } + + const projectGateways = await knex(TableName.ProjectGateway).where("projectId", projectId); + if (projectGateways.length) { + await knex.batchInsert( + TableName.ProjectGateway, + projectGateways.map((el) => { + const id = uuidV4(); + return { ...el, id, projectId: newProjectId }; + }) + ); + } + + const projectSlackConfigs = await knex(TableName.ProjectSlackConfigs).where("projectId", projectId); + if (projectSlackConfigs.length) { + await knex.batchInsert( + TableName.ProjectSlackConfigs, + projectSlackConfigs.map((el) => { + const id = uuidV4(); + return { ...el, id, projectId: newProjectId }; + }) + ); + } + + const projectMicrosoftTeamsConfigs = await knex(TableName.ProjectMicrosoftTeamsConfigs).where("projectId", projectId); + if (projectMicrosoftTeamsConfigs.length) { + await knex.batchInsert( + TableName.ProjectMicrosoftTeamsConfigs, + projectMicrosoftTeamsConfigs.map((el) => { + const id = uuidV4(); + return { ...el, id, projectId: newProjectId }; + }) + ); + } + + const trustedIps = await knex(TableName.TrustedIps).where("projectId", projectId); + if (trustedIps.length) { + await knex.batchInsert( + TableName.TrustedIps, + trustedIps.map((el) => { + const id = uuidV4(); + return { ...el, id, projectId: newProjectId }; + }) + ); + } + + return newProjectId; +}; + +const kickOutSecretManagerProject = async (knex: Knex, oldProjectId: string) => { + const newProjectId = await newProject(knex, oldProjectId, ProjectType.SecretManager); + await knex(TableName.IntegrationAuth).where("projectId", oldProjectId).update("projectId", newProjectId); + await knex(TableName.Environment).where("projectId", oldProjectId).update("projectId", newProjectId); + await knex(TableName.SecretBlindIndex).where("projectId", oldProjectId).update("projectId", newProjectId); + await knex(TableName.SecretSync).where("projectId", oldProjectId).update("projectId", newProjectId); + await knex(TableName.SecretTag).where("projectId", oldProjectId).update("projectId", newProjectId); + await knex(TableName.SecretReminderRecipients).where("projectId", oldProjectId).update("projectId", newProjectId); + await knex(TableName.ServiceToken).where("projectId", oldProjectId).update("projectId", newProjectId); +}; + +const kickOutCertManagerProject = async (knex: Knex, oldProjectId: string) => { + const newProjectId = await newProject(knex, oldProjectId, ProjectType.CertificateManager); + await knex(TableName.CertificateAuthority).where("projectId", oldProjectId).update("projectId", newProjectId); + await knex(TableName.Certificate).where("projectId", oldProjectId).update("projectId", newProjectId); + await knex(TableName.PkiSubscriber).where("projectId", oldProjectId).update("projectId", newProjectId); + await knex(TableName.PkiCollection).where("projectId", oldProjectId).update("projectId", newProjectId); + await knex(TableName.PkiAlert).where("projectId", oldProjectId).update("projectId", newProjectId); +}; + +const kickOutSecretScanningProject = async (knex: Knex, oldProjectId: string) => { + const newProjectId = await newProject(knex, oldProjectId, ProjectType.SecretScanning); + await knex(TableName.SecretScanningConfig).where("projectId", oldProjectId).update("projectId", newProjectId); + await knex(TableName.SecretScanningDataSource).where("projectId", oldProjectId).update("projectId", newProjectId); + await knex(TableName.SecretScanningFinding).where("projectId", oldProjectId).update("projectId", newProjectId); +}; + +const kickOutKmsProject = async (knex: Knex, oldProjectId: string) => { + const newProjectId = await newProject(knex, oldProjectId, ProjectType.KMS); + await knex(TableName.KmsKey) + .where("projectId", oldProjectId) + .andWhere("isReserved", false) + .update("projectId", newProjectId); + await knex(TableName.KmipClient).where("projectId", oldProjectId).update("projectId", newProjectId); +}; + +const kickOutSshProject = async (knex: Knex, oldProjectId: string) => { + const newProjectId = await newProject(knex, oldProjectId, ProjectType.SSH); + await knex(TableName.SshHost).where("projectId", oldProjectId).update("projectId", newProjectId); + await knex(TableName.ProjectSshConfig).where("projectId", oldProjectId).update("projectId", newProjectId); + await knex(TableName.SshCertificateAuthority).where("projectId", oldProjectId).update("projectId", newProjectId); + await knex(TableName.SshHostGroup).where("projectId", oldProjectId).update("projectId", newProjectId); +}; + +const BATCH_SIZE = 1000; +const MIGRATION_TIMEOUT = 30 * 60 * 1000; // 30 minutes + +export async function up(knex: Knex): Promise { + const result = await knex.raw("SHOW statement_timeout"); + const originalTimeout = result.rows[0].statement_timeout; + + try { + await knex.raw(`SET statement_timeout = ${MIGRATION_TIMEOUT}`); + + const hasTemplateTypeColumn = await knex.schema.hasColumn(TableName.ProjectTemplates, "type"); + if (hasTemplateTypeColumn) { + await knex(TableName.ProjectTemplates).whereNull("type").update({ + type: ProjectType.SecretManager + }); + await knex.schema.alterTable(TableName.ProjectTemplates, (t) => { + t.string("type").notNullable().defaultTo(ProjectType.SecretManager).alter(); + }); + } + + const hasTypeColumn = await knex.schema.hasColumn(TableName.Project, "type"); + const hasDefaultTypeColumn = await knex.schema.hasColumn(TableName.Project, "defaultProduct"); + if (hasTypeColumn && hasDefaultTypeColumn) { + await knex(TableName.Project).update({ + // eslint-disable-next-line + // @ts-ignore this is because this field is created later + type: knex.raw(`"defaultProduct"`) + }); + + await knex.schema.alterTable(TableName.Project, (t) => { + t.string("type").notNullable().alter(); + t.string("defaultProduct").nullable().alter(); + }); + + // Get all projects that need kickouts in a single query + const projectsNeedingKickouts = await getProjectsNeedingKickouts(knex); + + // Process projects in batches to avoid overwhelming the database + for (let i = 0; i < projectsNeedingKickouts.length; i += projectsNeedingKickouts.length) { + const batch = projectsNeedingKickouts.slice(i, i + BATCH_SIZE); + const processedIds: string[] = []; + + for (const project of batch) { + const kickoutPromises: Promise[] = []; + + // Only add kickouts that are actually needed (flags are pre-computed) + if (project.needsSecretManager) { + kickoutPromises.push(kickOutSecretManagerProject(knex, project.id)); + } + if (project.needsCertManager) { + kickoutPromises.push(kickOutCertManagerProject(knex, project.id)); + } + if (project.needsKms) { + kickoutPromises.push(kickOutKmsProject(knex, project.id)); + } + if (project.needsSsh) { + kickoutPromises.push(kickOutSshProject(knex, project.id)); + } + if (project.needsSecretScanning) { + kickoutPromises.push(kickOutSecretScanningProject(knex, project.id)); + } + + // Execute all kickouts in parallel and handle any failures gracefully + if (kickoutPromises.length > 0) { + const results = await Promise.allSettled(kickoutPromises); + + // Log any failures for debugging + results.forEach((res) => { + if (res.status === "rejected") { + throw new Error(`Migration failed for project ${project.id}: ${res.reason}`); + } + }); + } + + processedIds.push(project.id); + } + + // Clear defaultProduct for the processed batch + if (processedIds.length > 0) { + await knex(TableName.Project).whereIn("id", processedIds).update("defaultProduct", null); + } + } + } + } finally { + await knex.raw(`SET statement_timeout = '${originalTimeout}'`); + } +} + +export async function down(knex: Knex): Promise { + const hasTypeColumn = await knex.schema.hasColumn(TableName.Project, "type"); + const hasDefaultTypeColumn = await knex.schema.hasColumn(TableName.Project, "defaultProduct"); + if (hasTypeColumn && hasDefaultTypeColumn) { + await knex(TableName.Project).update({ + // eslint-disable-next-line + // @ts-ignore this is because this field is created later + defaultProduct: knex.raw(` + CASE + WHEN "type" IS NULL OR "type" = '' THEN 'secret-manager' + ELSE "type" + END + `) + }); + + await knex.schema.alterTable(TableName.Project, (t) => { + t.string("type").nullable().alter(); + t.string("defaultProduct").notNullable().alter(); + }); + } + + const hasTemplateTypeColumn = await knex.schema.hasColumn(TableName.ProjectTemplates, "type"); + if (hasTemplateTypeColumn) { + await knex.schema.alterTable(TableName.ProjectTemplates, (t) => { + t.string("type").nullable().alter(); + }); + } +} + diff --git a/backend/src/db/migrations/20250721101756_bump-aws-arn-field-size.ts b/backend/src/db/migrations/20250721101756_bump-aws-arn-field-size.ts new file mode 100644 index 000000000..1814df472 --- /dev/null +++ b/backend/src/db/migrations/20250721101756_bump-aws-arn-field-size.ts @@ -0,0 +1,21 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; + +export async function up(knex: Knex): Promise { + const hasColumn = await knex.schema.hasColumn(TableName.IdentityAwsAuth, "allowedPrincipalArns"); + if (hasColumn) { + await knex.schema.alterTable(TableName.IdentityAwsAuth, (t) => { + t.string("allowedPrincipalArns", 4096).notNullable().alter(); + }); + } +} + +export async function down(knex: Knex): Promise { + const hasColumn = await knex.schema.hasColumn(TableName.IdentityAwsAuth, "allowedPrincipalArns"); + if (hasColumn) { + await knex.schema.alterTable(TableName.IdentityAwsAuth, (t) => { + t.string("allowedPrincipalArns", 2048).notNullable().alter(); + }); + } +} diff --git a/backend/src/db/schemas/app-connections.ts b/backend/src/db/schemas/app-connections.ts index ee4282b73..2218b75ce 100644 --- a/backend/src/db/schemas/app-connections.ts +++ b/backend/src/db/schemas/app-connections.ts @@ -20,7 +20,8 @@ export const AppConnectionsSchema = z.object({ orgId: z.string().uuid(), createdAt: z.date(), updatedAt: z.date(), - isPlatformManagedCredentials: z.boolean().default(false).nullable().optional() + isPlatformManagedCredentials: z.boolean().default(false).nullable().optional(), + gatewayId: z.string().uuid().nullable().optional() }); export type TAppConnections = z.infer; diff --git a/backend/src/db/schemas/models.ts b/backend/src/db/schemas/models.ts index 8d7b2e69d..2e71486bf 100644 --- a/backend/src/db/schemas/models.ts +++ b/backend/src/db/schemas/models.ts @@ -270,6 +270,16 @@ export enum ProjectType { SecretScanning = "secret-scanning" } +export enum ActionProjectType { + SecretManager = ProjectType.SecretManager, + CertificateManager = ProjectType.CertificateManager, + KMS = ProjectType.KMS, + SSH = ProjectType.SSH, + SecretScanning = ProjectType.SecretScanning, + // project operations that happen on all types + Any = "any" +} + export enum SortDirection { ASC = "asc", DESC = "desc" diff --git a/backend/src/db/schemas/project-templates.ts b/backend/src/db/schemas/project-templates.ts index d1fe29a80..f12386165 100644 --- a/backend/src/db/schemas/project-templates.ts +++ b/backend/src/db/schemas/project-templates.ts @@ -16,7 +16,7 @@ export const ProjectTemplatesSchema = z.object({ orgId: z.string().uuid(), createdAt: z.date(), updatedAt: z.date(), - type: z.string().nullable().optional() + type: z.string().default("secret-manager") }); export type TProjectTemplates = z.infer; diff --git a/backend/src/db/schemas/projects.ts b/backend/src/db/schemas/projects.ts index 00401575e..059565a94 100644 --- a/backend/src/db/schemas/projects.ts +++ b/backend/src/db/schemas/projects.ts @@ -25,12 +25,12 @@ export const ProjectsSchema = z.object({ kmsSecretManagerKeyId: z.string().uuid().nullable().optional(), kmsSecretManagerEncryptedDataKey: zodBuffer.nullable().optional(), description: z.string().nullable().optional(), - type: z.string().nullable().optional(), + type: z.string(), enforceCapitalization: z.boolean().default(false), hasDeleteProtection: z.boolean().default(false).nullable().optional(), secretSharing: z.boolean().default(true), showSnapshotsLegacy: z.boolean().default(false), - defaultProduct: z.string().default("secret-manager") + defaultProduct: z.string().nullable().optional() }); export type TProjects = z.infer; diff --git a/backend/src/ee/routes/v1/pit-router.ts b/backend/src/ee/routes/v1/pit-router.ts index f993e31d7..14a82bce4 100644 --- a/backend/src/ee/routes/v1/pit-router.ts +++ b/backend/src/ee/routes/v1/pit-router.ts @@ -3,11 +3,14 @@ import { z } from "zod"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { removeTrailingSlash } from "@app/lib/fn"; -import { readLimit } from "@app/server/config/rateLimiter"; +import { isValidFolderName } from "@app/lib/validator"; +import { readLimit, secretsLimit } from "@app/server/config/rateLimiter"; +import { SecretNameSchema } from "@app/server/lib/schemas"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { booleanSchema } from "@app/server/routes/sanitizedSchemas"; import { AuthMode } from "@app/services/auth/auth-type"; import { commitChangesResponseSchema, resourceChangeSchema } from "@app/services/folder-commit/folder-commit-schemas"; +import { ResourceMetadataSchema } from "@app/services/resource-metadata/resource-metadata-schema"; const commitHistoryItemSchema = z.object({ id: z.string(), @@ -413,4 +416,166 @@ export const registerPITRouter = async (server: FastifyZodProvider) => { return result; } }); + + server.route({ + method: "POST", + url: "/batch/commit", + config: { + rateLimit: secretsLimit + }, + schema: { + hide: true, + description: "Commit changes", + security: [ + { + bearerAuth: [] + } + ], + body: z.object({ + projectId: z.string().trim(), + environment: z.string().trim(), + secretPath: z.string().trim().default("/").transform(removeTrailingSlash), + message: z + .string() + .trim() + .min(1) + .max(255) + .refine((message) => message.trim() !== "", { + message: "Commit message cannot be empty" + }), + changes: z.object({ + secrets: z.object({ + create: z + .array( + z.object({ + secretKey: SecretNameSchema, + secretValue: z.string().transform((val) => (val.at(-1) === "\n" ? `${val.trim()}\n` : val.trim())), + secretComment: z.string().trim().optional().default(""), + skipMultilineEncoding: z.boolean().optional(), + metadata: z.record(z.string()).optional(), + secretMetadata: ResourceMetadataSchema.optional(), + tagIds: z.string().array().optional() + }) + ) + .optional(), + update: z + .array( + z.object({ + secretKey: SecretNameSchema, + newSecretName: SecretNameSchema.optional(), + secretValue: z + .string() + .transform((val) => (val.at(-1) === "\n" ? `${val.trim()}\n` : val.trim())) + .optional(), + secretComment: z.string().trim().optional().default(""), + skipMultilineEncoding: z.boolean().optional(), + metadata: z.record(z.string()).optional(), + secretMetadata: ResourceMetadataSchema.optional(), + tagIds: z.string().array().optional() + }) + ) + .optional(), + delete: z + .array( + z.object({ + secretKey: SecretNameSchema + }) + ) + .optional() + }), + folders: z.object({ + create: z + .array( + z.object({ + folderName: z + .string() + .trim() + .refine((name) => isValidFolderName(name), { + message: "Invalid folder name. Only alphanumeric characters, dashes, and underscores are allowed." + }), + description: z.string().optional() + }) + ) + .optional(), + update: z + .array( + z.object({ + folderName: z + .string() + .trim() + .refine((name) => isValidFolderName(name), { + message: "Invalid folder name. Only alphanumeric characters, dashes, and underscores are allowed." + }), + description: z.string().nullable().optional(), + id: z.string() + }) + ) + .optional(), + delete: z + .array( + z.object({ + folderName: z + .string() + .trim() + .refine((name) => isValidFolderName(name), { + message: "Invalid folder name. Only alphanumeric characters, dashes, and underscores are allowed." + }), + id: z.string() + }) + ) + .optional() + }) + }) + }), + response: { + 200: z.object({ + message: z.string() + }) + } + }, + onRequest: verifyAuth([AuthMode.JWT]), + handler: async (req) => { + const result = await server.services.pit.processNewCommitRaw({ + actorId: req.permission.id, + actor: req.permission.type, + actorOrgId: req.permission.orgId, + actorAuthMethod: req.permission.authMethod, + projectId: req.body.projectId, + environment: req.body.environment, + secretPath: req.body.secretPath, + message: req.body.message, + changes: { + secrets: req.body.changes.secrets, + folders: req.body.changes.folders + } + }); + + await server.services.auditLog.createAuditLog({ + ...req.auditLogInfo, + projectId: req.body.projectId, + event: { + type: EventType.PIT_PROCESS_NEW_COMMIT_RAW, + metadata: { + commitId: result.commitId, + approvalId: result.approvalId, + projectId: req.body.projectId, + environment: req.body.environment, + secretPath: req.body.secretPath, + message: req.body.message + } + } + }); + + for await (const event of result.secretMutationEvents) { + await server.services.auditLog.createAuditLog({ + ...req.auditLogInfo, + orgId: req.permission.orgId, + projectId: req.body.projectId, + event + }); + } + + return { message: "success" }; + } + }); }; diff --git a/backend/src/ee/routes/v1/project-template-router.ts b/backend/src/ee/routes/v1/project-template-router.ts index a00f4aa0b..c157b628b 100644 --- a/backend/src/ee/routes/v1/project-template-router.ts +++ b/backend/src/ee/routes/v1/project-template-router.ts @@ -1,6 +1,6 @@ import { z } from "zod"; -import { ProjectMembershipRole, ProjectTemplatesSchema } from "@app/db/schemas"; +import { ProjectMembershipRole, ProjectTemplatesSchema, ProjectType } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { ProjectPermissionV2Schema } from "@app/ee/services/permission/project-permission"; import { isInfisicalProjectTemplate } from "@app/ee/services/project-template/project-template-fns"; @@ -104,6 +104,9 @@ export const registerProjectTemplateRouter = async (server: FastifyZodProvider) hide: false, tags: [ApiDocsTags.ProjectTemplates], description: "List project templates for the current organization.", + querystring: z.object({ + type: z.nativeEnum(ProjectType).optional().describe(ProjectTemplates.LIST.type) + }), response: { 200: z.object({ projectTemplates: SanitizedProjectTemplateSchema.array() @@ -112,7 +115,10 @@ export const registerProjectTemplateRouter = async (server: FastifyZodProvider) }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { - const projectTemplates = await server.services.projectTemplate.listProjectTemplatesByOrg(req.permission); + const projectTemplates = await server.services.projectTemplate.listProjectTemplatesByOrg( + req.permission, + req.query.type + ); const auditTemplates = projectTemplates.filter((template) => !isInfisicalProjectTemplate(template.name)); @@ -191,6 +197,7 @@ export const registerProjectTemplateRouter = async (server: FastifyZodProvider) .describe(ProjectTemplates.CREATE.name), description: z.string().max(256).trim().optional().describe(ProjectTemplates.CREATE.description), roles: ProjectTemplateRolesSchema.default([]).describe(ProjectTemplates.CREATE.roles), + type: z.nativeEnum(ProjectType).describe(ProjectTemplates.CREATE.type), environments: ProjectTemplateEnvironmentsSchema.describe(ProjectTemplates.CREATE.environments).optional() }), response: { diff --git a/backend/src/ee/routes/v2/secret-rotation-v2-routers/index.ts b/backend/src/ee/routes/v2/secret-rotation-v2-routers/index.ts index 5d4ccc021..5f8dea5d7 100644 --- a/backend/src/ee/routes/v2/secret-rotation-v2-routers/index.ts +++ b/backend/src/ee/routes/v2/secret-rotation-v2-routers/index.ts @@ -6,6 +6,7 @@ import { registerAzureClientSecretRotationRouter } from "./azure-client-secret-r import { registerLdapPasswordRotationRouter } from "./ldap-password-rotation-router"; import { registerMsSqlCredentialsRotationRouter } from "./mssql-credentials-rotation-router"; import { registerMySqlCredentialsRotationRouter } from "./mysql-credentials-rotation-router"; +import { registerOktaClientSecretRotationRouter } from "./okta-client-secret-rotation-router"; import { registerOracleDBCredentialsRotationRouter } from "./oracledb-credentials-rotation-router"; import { registerPostgresCredentialsRotationRouter } from "./postgres-credentials-rotation-router"; @@ -22,5 +23,6 @@ export const SECRET_ROTATION_REGISTER_ROUTER_MAP: Record< [SecretRotation.Auth0ClientSecret]: registerAuth0ClientSecretRotationRouter, [SecretRotation.AzureClientSecret]: registerAzureClientSecretRotationRouter, [SecretRotation.AwsIamUserSecret]: registerAwsIamUserSecretRotationRouter, - [SecretRotation.LdapPassword]: registerLdapPasswordRotationRouter + [SecretRotation.LdapPassword]: registerLdapPasswordRotationRouter, + [SecretRotation.OktaClientSecret]: registerOktaClientSecretRotationRouter }; diff --git a/backend/src/ee/routes/v2/secret-rotation-v2-routers/okta-client-secret-rotation-router.ts b/backend/src/ee/routes/v2/secret-rotation-v2-routers/okta-client-secret-rotation-router.ts new file mode 100644 index 000000000..133a70457 --- /dev/null +++ b/backend/src/ee/routes/v2/secret-rotation-v2-routers/okta-client-secret-rotation-router.ts @@ -0,0 +1,19 @@ +import { + CreateOktaClientSecretRotationSchema, + OktaClientSecretRotationGeneratedCredentialsSchema, + OktaClientSecretRotationSchema, + UpdateOktaClientSecretRotationSchema +} from "@app/ee/services/secret-rotation-v2/okta-client-secret"; +import { SecretRotation } from "@app/ee/services/secret-rotation-v2/secret-rotation-v2-enums"; + +import { registerSecretRotationEndpoints } from "./secret-rotation-v2-endpoints"; + +export const registerOktaClientSecretRotationRouter = async (server: FastifyZodProvider) => + registerSecretRotationEndpoints({ + type: SecretRotation.OktaClientSecret, + server, + responseSchema: OktaClientSecretRotationSchema, + createSchema: CreateOktaClientSecretRotationSchema, + updateSchema: UpdateOktaClientSecretRotationSchema, + generatedCredentialsSchema: OktaClientSecretRotationGeneratedCredentialsSchema + }); diff --git a/backend/src/ee/routes/v2/secret-rotation-v2-routers/secret-rotation-v2-router.ts b/backend/src/ee/routes/v2/secret-rotation-v2-routers/secret-rotation-v2-router.ts index 86768c3ad..7db99c8c4 100644 --- a/backend/src/ee/routes/v2/secret-rotation-v2-routers/secret-rotation-v2-router.ts +++ b/backend/src/ee/routes/v2/secret-rotation-v2-routers/secret-rotation-v2-router.ts @@ -7,6 +7,7 @@ import { AzureClientSecretRotationListItemSchema } from "@app/ee/services/secret import { LdapPasswordRotationListItemSchema } from "@app/ee/services/secret-rotation-v2/ldap-password"; import { MsSqlCredentialsRotationListItemSchema } from "@app/ee/services/secret-rotation-v2/mssql-credentials"; import { MySqlCredentialsRotationListItemSchema } from "@app/ee/services/secret-rotation-v2/mysql-credentials"; +import { OktaClientSecretRotationListItemSchema } from "@app/ee/services/secret-rotation-v2/okta-client-secret"; import { OracleDBCredentialsRotationListItemSchema } from "@app/ee/services/secret-rotation-v2/oracledb-credentials"; import { PostgresCredentialsRotationListItemSchema } from "@app/ee/services/secret-rotation-v2/postgres-credentials"; import { SecretRotationV2Schema } from "@app/ee/services/secret-rotation-v2/secret-rotation-v2-union-schema"; @@ -23,7 +24,8 @@ const SecretRotationV2OptionsSchema = z.discriminatedUnion("type", [ Auth0ClientSecretRotationListItemSchema, AzureClientSecretRotationListItemSchema, AwsIamUserSecretRotationListItemSchema, - LdapPasswordRotationListItemSchema + LdapPasswordRotationListItemSchema, + OktaClientSecretRotationListItemSchema ]); export const registerSecretRotationV2Router = async (server: FastifyZodProvider) => { diff --git a/backend/src/ee/services/access-approval-policy/access-approval-policy-service.ts b/backend/src/ee/services/access-approval-policy/access-approval-policy-service.ts index fa487d0b7..6d656bafa 100644 --- a/backend/src/ee/services/access-approval-policy/access-approval-policy-service.ts +++ b/backend/src/ee/services/access-approval-policy/access-approval-policy-service.ts @@ -1,5 +1,6 @@ import { ForbiddenError } from "@casl/ability"; +import { ActionProjectType } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors"; @@ -116,7 +117,8 @@ export const accessApprovalPolicyServiceFactory = ({ actorId, projectId: project.id, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -272,7 +274,8 @@ export const accessApprovalPolicyServiceFactory = ({ actorId, projectId: project.id, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const accessApprovalPolicies = await accessApprovalPolicyDAL.find({ projectId: project.id, deletedAt: null }); @@ -337,7 +340,8 @@ export const accessApprovalPolicyServiceFactory = ({ actorId, projectId: accessApprovalPolicy.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.SecretApproval); @@ -533,7 +537,8 @@ export const accessApprovalPolicyServiceFactory = ({ actorId, projectId: policy.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Delete, @@ -583,7 +588,8 @@ export const accessApprovalPolicyServiceFactory = ({ actorId, projectId: project.id, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); if (!membership) { throw new ForbiddenRequestError({ message: "You are not a member of this project" }); @@ -622,7 +628,8 @@ export const accessApprovalPolicyServiceFactory = ({ actorId, projectId: policy.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretApproval); diff --git a/backend/src/ee/services/access-approval-request/access-approval-request-service.ts b/backend/src/ee/services/access-approval-request/access-approval-request-service.ts index 8b823ee91..bdf579616 100644 --- a/backend/src/ee/services/access-approval-request/access-approval-request-service.ts +++ b/backend/src/ee/services/access-approval-request/access-approval-request-service.ts @@ -1,7 +1,7 @@ import slugify from "@sindresorhus/slugify"; import msFn from "ms"; -import { ProjectMembershipRole } from "@app/db/schemas"; +import { ActionProjectType, ProjectMembershipRole } from "@app/db/schemas"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors"; import { groupBy } from "@app/lib/fn"; @@ -107,7 +107,8 @@ export const accessApprovalRequestServiceFactory = ({ actorId, projectId: project.id, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); if (!membership) { throw new ForbiddenRequestError({ message: "You are not a member of this project" }); @@ -216,7 +217,7 @@ export const accessApprovalRequestServiceFactory = ({ ); const requesterFullName = `${requestedByUser.firstName} ${requestedByUser.lastName}`; - const approvalUrl = `${cfg.SITE_URL}/projects/${project.id}/secret-manager/approval`; + const approvalUrl = `${cfg.SITE_URL}/projects/secret-management/${project.id}/approval`; await triggerWorkflowIntegrationNotification({ input: { @@ -289,7 +290,8 @@ export const accessApprovalRequestServiceFactory = ({ actorId, projectId: project.id, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); if (!membership) { throw new ForbiddenRequestError({ message: "You are not a member of this project" }); @@ -335,7 +337,8 @@ export const accessApprovalRequestServiceFactory = ({ actorId, projectId: accessApprovalRequest.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); if (!membership) { @@ -551,7 +554,7 @@ export const accessApprovalRequestServiceFactory = ({ bypassReason: bypassReason || "No reason provided", secretPath: policy.secretPath || "/", environment, - approvalUrl: `${cfg.SITE_URL}/projects/${project.id}/secret-manager/approval`, + approvalUrl: `${cfg.SITE_URL}/projects/secret-management/${project.id}/approval`, requestType: "access" }, template: SmtpTemplates.AccessSecretRequestBypassed @@ -582,7 +585,8 @@ export const accessApprovalRequestServiceFactory = ({ actorId, projectId: project.id, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); if (!membership) { throw new ForbiddenRequestError({ message: "You are not a member of this project" }); diff --git a/backend/src/ee/services/app-connections/oracledb/oracledb-connection-schemas.ts b/backend/src/ee/services/app-connections/oracledb/oracledb-connection-schemas.ts index f93abae83..38e0fc828 100644 --- a/backend/src/ee/services/app-connections/oracledb/oracledb-connection-schemas.ts +++ b/backend/src/ee/services/app-connections/oracledb/oracledb-connection-schemas.ts @@ -45,7 +45,10 @@ export const ValidateOracleDBConnectionCredentialsSchema = z.discriminatedUnion( ]); export const CreateOracleDBConnectionSchema = ValidateOracleDBConnectionCredentialsSchema.and( - GenericCreateAppConnectionFieldsSchema(AppConnection.OracleDB, { supportsPlatformManagedCredentials: true }) + GenericCreateAppConnectionFieldsSchema(AppConnection.OracleDB, { + supportsPlatformManagedCredentials: true, + supportsGateways: true + }) ); export const UpdateOracleDBConnectionSchema = z @@ -54,7 +57,12 @@ export const UpdateOracleDBConnectionSchema = z AppConnections.UPDATE(AppConnection.OracleDB).credentials ) }) - .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.OracleDB, { supportsPlatformManagedCredentials: true })); + .and( + GenericUpdateAppConnectionFieldsSchema(AppConnection.OracleDB, { + supportsPlatformManagedCredentials: true, + supportsGateways: true + }) + ); export const OracleDBConnectionListItemSchema = z.object({ name: z.literal("OracleDB"), diff --git a/backend/src/ee/services/assume-privilege/assume-privilege-service.ts b/backend/src/ee/services/assume-privilege/assume-privilege-service.ts index a63b0e3be..0c3d28364 100644 --- a/backend/src/ee/services/assume-privilege/assume-privilege-service.ts +++ b/backend/src/ee/services/assume-privilege/assume-privilege-service.ts @@ -1,5 +1,6 @@ import { ForbiddenError } from "@casl/ability"; +import { ActionProjectType } from "@app/db/schemas"; import { getConfig } from "@app/lib/config/env"; import { crypto } from "@app/lib/crypto/cryptography"; import { ForbiddenRequestError, NotFoundError } from "@app/lib/errors"; @@ -37,7 +38,8 @@ export const assumePrivilegeServiceFactory = ({ actorId: actorPermissionDetails.id, projectId, actorAuthMethod: actorPermissionDetails.authMethod, - actorOrgId: actorPermissionDetails.orgId + actorOrgId: actorPermissionDetails.orgId, + actionProjectType: ActionProjectType.Any }); if (targetActorType === ActorType.USER) { @@ -58,7 +60,8 @@ export const assumePrivilegeServiceFactory = ({ actorId: targetActorId, projectId, actorAuthMethod: actorPermissionDetails.authMethod, - actorOrgId: actorPermissionDetails.orgId + actorOrgId: actorPermissionDetails.orgId, + actionProjectType: ActionProjectType.Any }); const appCfg = getConfig(); diff --git a/backend/src/ee/services/audit-log/audit-log-service.ts b/backend/src/ee/services/audit-log/audit-log-service.ts index 333847734..06186d54b 100644 --- a/backend/src/ee/services/audit-log/audit-log-service.ts +++ b/backend/src/ee/services/audit-log/audit-log-service.ts @@ -1,6 +1,7 @@ import { ForbiddenError } from "@casl/ability"; import { requestContext } from "@fastify/request-context"; +import { ActionProjectType } from "@app/db/schemas"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError } from "@app/lib/errors"; import { ActorType } from "@app/services/auth/auth-type"; @@ -37,7 +38,8 @@ export const auditLogServiceFactory = ({ actorId, projectId: filter.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.AuditLogs); } else { diff --git a/backend/src/ee/services/audit-log/audit-log-types.ts b/backend/src/ee/services/audit-log/audit-log-types.ts index 7ae3c267c..818bb1f99 100644 --- a/backend/src/ee/services/audit-log/audit-log-types.ts +++ b/backend/src/ee/services/audit-log/audit-log-types.ts @@ -449,6 +449,7 @@ export enum EventType { PIT_REVERT_COMMIT = "pit-revert-commit", PIT_GET_FOLDER_STATE = "pit-get-folder-state", PIT_COMPARE_FOLDER_STATES = "pit-compare-folder-states", + PIT_PROCESS_NEW_COMMIT_RAW = "pit-process-new-commit-raw", SECRET_SCANNING_DATA_SOURCE_LIST = "secret-scanning-data-source-list", SECRET_SCANNING_DATA_SOURCE_CREATE = "secret-scanning-data-source-create", SECRET_SCANNING_DATA_SOURCE_UPDATE = "secret-scanning-data-source-update", @@ -1550,8 +1551,9 @@ interface UpdateFolderEvent { metadata: { environment: string; folderId: string; - oldFolderName: string; + oldFolderName?: string; newFolderName: string; + newFolderDescription?: string; folderPath: string; }; } @@ -3226,6 +3228,18 @@ interface PitCompareFolderStatesEvent { }; } +interface PitProcessNewCommitRawEvent { + type: EventType.PIT_PROCESS_NEW_COMMIT_RAW; + metadata: { + projectId: string; + environment: string; + secretPath: string; + message: string; + approvalId?: string; + commitId?: string; + }; +} + interface SecretScanningDataSourceListEvent { type: EventType.SECRET_SCANNING_DATA_SOURCE_LIST; metadata: { @@ -3687,6 +3701,7 @@ export type Event = | PitRevertCommitEvent | PitCompareFolderStatesEvent | PitGetFolderStateEvent + | PitProcessNewCommitRawEvent | SecretScanningDataSourceListEvent | SecretScanningDataSourceGetEvent | SecretScanningDataSourceCreateEvent diff --git a/backend/src/ee/services/certificate-authority-crl/certificate-authority-crl-service.ts b/backend/src/ee/services/certificate-authority-crl/certificate-authority-crl-service.ts index cc6a6b5fe..5ead798fa 100644 --- a/backend/src/ee/services/certificate-authority-crl/certificate-authority-crl-service.ts +++ b/backend/src/ee/services/certificate-authority-crl/certificate-authority-crl-service.ts @@ -1,6 +1,7 @@ import { ForbiddenError } from "@casl/ability"; import * as x509 from "@peculiar/x509"; +import { ActionProjectType } from "@app/db/schemas"; import { TCertificateAuthorityCrlDALFactory } from "@app/ee/services/certificate-authority-crl/certificate-authority-crl-dal"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; @@ -77,7 +78,8 @@ export const certificateAuthorityCrlServiceFactory = ({ actorId, projectId: ca.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( diff --git a/backend/src/ee/services/dynamic-secret-lease/dynamic-secret-lease-service.ts b/backend/src/ee/services/dynamic-secret-lease/dynamic-secret-lease-service.ts index c2c596922..cf37626c7 100644 --- a/backend/src/ee/services/dynamic-secret-lease/dynamic-secret-lease-service.ts +++ b/backend/src/ee/services/dynamic-secret-lease/dynamic-secret-lease-service.ts @@ -1,6 +1,7 @@ import { ForbiddenError, subject } from "@casl/ability"; import RE2 from "re2"; +import { ActionProjectType } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { @@ -84,7 +85,8 @@ export const dynamicSecretLeaseServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const plan = await licenseService.getPlan(actorOrgId); @@ -200,7 +202,8 @@ export const dynamicSecretLeaseServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const { decryptor: secretManagerDecryptor } = await kmsService.createCipherPairWithDataKey({ @@ -297,7 +300,8 @@ export const dynamicSecretLeaseServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const { decryptor: secretManagerDecryptor } = await kmsService.createCipherPairWithDataKey({ @@ -385,7 +389,8 @@ export const dynamicSecretLeaseServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path); @@ -432,7 +437,8 @@ export const dynamicSecretLeaseServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path); diff --git a/backend/src/ee/services/dynamic-secret/dynamic-secret-service.ts b/backend/src/ee/services/dynamic-secret/dynamic-secret-service.ts index ab59b1a1d..73dcbe6e3 100644 --- a/backend/src/ee/services/dynamic-secret/dynamic-secret-service.ts +++ b/backend/src/ee/services/dynamic-secret/dynamic-secret-service.ts @@ -1,5 +1,6 @@ import { ForbiddenError, subject } from "@casl/ability"; +import { ActionProjectType } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { @@ -78,7 +79,8 @@ export const dynamicSecretServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -207,7 +209,8 @@ export const dynamicSecretServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const plan = await licenseService.getPlan(actorOrgId); @@ -358,7 +361,8 @@ export const dynamicSecretServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path); @@ -423,7 +427,8 @@ export const dynamicSecretServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path); @@ -487,7 +492,8 @@ export const dynamicSecretServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); // verify user has access to each env in request @@ -530,7 +536,8 @@ export const dynamicSecretServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionDynamicSecretActions.ReadRootCredential, @@ -578,7 +585,8 @@ export const dynamicSecretServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path); @@ -615,7 +623,8 @@ export const dynamicSecretServiceFactory = ({ actorId: actor.id, projectId, actorAuthMethod: actor.authMethod, - actorOrgId: actor.orgId + actorOrgId: actor.orgId, + actionProjectType: ActionProjectType.SecretManager }); const userAccessibleFolderMappings = folderMappings.filter(({ path, environment }) => @@ -659,7 +668,8 @@ export const dynamicSecretServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const folders = await folderDAL.findBySecretPathMultiEnv(projectId, environmentSlugs, path); diff --git a/backend/src/ee/services/identity-project-additional-privilege-v2/identity-project-additional-privilege-v2-service.ts b/backend/src/ee/services/identity-project-additional-privilege-v2/identity-project-additional-privilege-v2-service.ts index 485e46885..64da588f8 100644 --- a/backend/src/ee/services/identity-project-additional-privilege-v2/identity-project-additional-privilege-v2-service.ts +++ b/backend/src/ee/services/identity-project-additional-privilege-v2/identity-project-additional-privilege-v2-service.ts @@ -1,7 +1,7 @@ import { ForbiddenError, subject } from "@casl/ability"; import { packRules } from "@casl/ability/extra"; -import { TableName } from "@app/db/schemas"; +import { ActionProjectType, TableName } from "@app/db/schemas"; import { BadRequestError, NotFoundError, PermissionBoundaryError } from "@app/lib/errors"; import { ms } from "@app/lib/ms"; import { validateHandlebarTemplate } from "@app/lib/template/validate-handlebars"; @@ -61,7 +61,8 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({ actorId, projectId: identityProjectMembership.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionIdentityActions.Edit, @@ -72,7 +73,8 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({ actorId: identityId, projectId: identityProjectMembership.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); // we need to validate that the privilege given is not higher than the assigning users permission @@ -158,7 +160,8 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({ actorId, projectId: identityProjectMembership.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionIdentityActions.Edit, @@ -169,7 +172,8 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({ actorId: identityProjectMembership.identityId, projectId: identityProjectMembership.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); // we need to validate that the privilege given is not higher than the assigning users permission @@ -256,7 +260,8 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({ actorId, projectId: identityProjectMembership.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionIdentityActions.Edit, @@ -267,7 +272,8 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({ actorId: identityProjectMembership.identityId, projectId: identityProjectMembership.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); const permissionBoundary = validatePrivilegeChangeOperation( membership.shouldUseNewPrivilegeSystem, @@ -315,7 +321,8 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({ actorId, projectId: identityProjectMembership.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionIdentityActions.Read, @@ -349,7 +356,8 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({ actorId, projectId: identityProjectMembership.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionIdentityActions.Read, @@ -384,7 +392,8 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({ actorId, projectId: identityProjectMembership.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionIdentityActions.Read, diff --git a/backend/src/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-service.ts b/backend/src/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-service.ts index 747e13f15..828cf43a3 100644 --- a/backend/src/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-service.ts +++ b/backend/src/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-service.ts @@ -1,6 +1,7 @@ import { ForbiddenError, MongoAbility, RawRuleOf, subject } from "@casl/ability"; import { PackRule, packRules, unpackRules } from "@casl/ability/extra"; +import { ActionProjectType } from "@app/db/schemas"; import { BadRequestError, NotFoundError, PermissionBoundaryError } from "@app/lib/errors"; import { ms } from "@app/lib/ms"; import { validateHandlebarTemplate } from "@app/lib/template/validate-handlebars"; @@ -72,7 +73,8 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({ actorId, projectId: identityProjectMembership.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan( @@ -85,7 +87,8 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({ actorId: identityId, projectId: identityProjectMembership.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); // we need to validate that the privilege given is not higher than the assigning users permission @@ -172,7 +175,8 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({ actorId, projectId: identityProjectMembership.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan( @@ -185,7 +189,8 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({ actorId: identityProjectMembership.identityId, projectId: identityProjectMembership.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); // we need to validate that the privilege given is not higher than the assigning users permission @@ -288,7 +293,8 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({ actorId, projectId: identityProjectMembership.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionIdentityActions.Edit, @@ -300,7 +306,8 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({ actorId: identityProjectMembership.identityId, projectId: identityProjectMembership.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); const permissionBoundary = validatePrivilegeChangeOperation( membership.shouldUseNewPrivilegeSystem, @@ -359,7 +366,8 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({ actorId, projectId: identityProjectMembership.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionIdentityActions.Read, @@ -401,7 +409,8 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({ actorId, projectId: identityProjectMembership.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan( diff --git a/backend/src/ee/services/kmip/kmip-service.ts b/backend/src/ee/services/kmip/kmip-service.ts index 992b31017..8daa5a37a 100644 --- a/backend/src/ee/services/kmip/kmip-service.ts +++ b/backend/src/ee/services/kmip/kmip-service.ts @@ -1,6 +1,7 @@ import { ForbiddenError } from "@casl/ability"; import * as x509 from "@peculiar/x509"; +import { ActionProjectType } from "@app/db/schemas"; import { crypto } from "@app/lib/crypto/cryptography"; import { BadRequestError, InternalServerError, NotFoundError } from "@app/lib/errors"; import { isValidIp } from "@app/lib/ip"; @@ -78,7 +79,8 @@ export const kmipServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.KMS }); ForbiddenError.from(permission).throwUnlessCan( @@ -131,7 +133,8 @@ export const kmipServiceFactory = ({ actorId, projectId: kmipClient.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.KMS }); ForbiddenError.from(permission).throwUnlessCan( @@ -162,7 +165,8 @@ export const kmipServiceFactory = ({ actorId, projectId: kmipClient.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.KMS }); ForbiddenError.from(permission).throwUnlessCan( @@ -195,7 +199,8 @@ export const kmipServiceFactory = ({ actorId, projectId: kmipClient.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.KMS }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionKmipActions.ReadClients, ProjectPermissionSub.Kmip); @@ -216,7 +221,8 @@ export const kmipServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.KMS }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionKmipActions.ReadClients, ProjectPermissionSub.Kmip); @@ -252,7 +258,8 @@ export const kmipServiceFactory = ({ actorId, projectId: kmipClient.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.KMS }); ForbiddenError.from(permission).throwUnlessCan( diff --git a/backend/src/ee/services/permission/permission-service-types.ts b/backend/src/ee/services/permission/permission-service-types.ts index 72df88982..5e71c65d9 100644 --- a/backend/src/ee/services/permission/permission-service-types.ts +++ b/backend/src/ee/services/permission/permission-service-types.ts @@ -1,6 +1,7 @@ import { MongoAbility, RawRuleOf } from "@casl/ability"; import { MongoQuery } from "@ucast/mongo2js"; +import { ActionProjectType } from "@app/db/schemas"; import { ActorAuthMethod, ActorType } from "@app/services/auth/auth-type"; import { OrgPermissionSet } from "./org-permission"; @@ -20,6 +21,7 @@ export type TGetUserProjectPermissionArg = { userId: string; projectId: string; authMethod: ActorAuthMethod; + actionProjectType: ActionProjectType; userOrgId?: string; }; @@ -27,12 +29,14 @@ export type TGetIdentityProjectPermissionArg = { identityId: string; projectId: string; identityOrgId?: string; + actionProjectType: ActionProjectType; }; export type TGetServiceTokenProjectPermissionArg = { serviceTokenId: string; projectId: string; actorOrgId?: string; + actionProjectType: ActionProjectType; }; export type TGetProjectPermissionArg = { @@ -41,6 +45,7 @@ export type TGetProjectPermissionArg = { projectId: string; actorAuthMethod: ActorAuthMethod; actorOrgId?: string; + actionProjectType: ActionProjectType; }; export type TPermissionServiceFactory = { @@ -138,7 +143,13 @@ export type TPermissionServiceFactory = { }; } >; - getUserProjectPermission: ({ userId, projectId, authMethod, userOrgId }: TGetUserProjectPermissionArg) => Promise<{ + getUserProjectPermission: ({ + userId, + projectId, + authMethod, + userOrgId, + actionProjectType + }: TGetUserProjectPermissionArg) => Promise<{ permission: MongoAbility; membership: { id: string; diff --git a/backend/src/ee/services/permission/permission-service.ts b/backend/src/ee/services/permission/permission-service.ts index 32c01dcfb..85ee82cca 100644 --- a/backend/src/ee/services/permission/permission-service.ts +++ b/backend/src/ee/services/permission/permission-service.ts @@ -5,6 +5,7 @@ import { MongoQuery } from "@ucast/mongo2js"; import handlebars from "handlebars"; import { + ActionProjectType, OrgMembershipRole, ProjectMembershipRole, ServiceTokenScopes, @@ -213,7 +214,8 @@ export const permissionServiceFactory = ({ userId, projectId, authMethod, - userOrgId + userOrgId, + actionProjectType }: TGetUserProjectPermissionArg): Promise> => { const userProjectPermission = await permissionDAL.getProjectPermission(userId, projectId); if (!userProjectPermission) throw new ForbiddenRequestError({ name: "User not a part of the specified project" }); @@ -240,6 +242,12 @@ export const permissionServiceFactory = ({ userProjectPermission.orgRole ); + if (actionProjectType !== ActionProjectType.Any && actionProjectType !== userProjectPermission.projectType) { + throw new BadRequestError({ + message: `The project is of type ${userProjectPermission.projectType}. Operations of type ${actionProjectType} are not allowed.` + }); + } + // join two permissions and pass to build the final permission set const rolePermissions = userProjectPermission.roles?.map(({ role, permissions }) => ({ role, permissions })) || []; const additionalPrivileges = @@ -287,7 +295,8 @@ export const permissionServiceFactory = ({ const getIdentityProjectPermission = async ({ identityId, projectId, - identityOrgId + identityOrgId, + actionProjectType }: TGetIdentityProjectPermissionArg): Promise> => { const identityProjectPermission = await permissionDAL.getProjectIdentityPermission(identityId, projectId); if (!identityProjectPermission) @@ -307,6 +316,12 @@ export const permissionServiceFactory = ({ throw new ForbiddenRequestError({ name: "Identity is not a member of the specified organization" }); } + if (actionProjectType !== ActionProjectType.Any && actionProjectType !== identityProjectPermission.projectType) { + throw new BadRequestError({ + message: `The project is of type ${identityProjectPermission.projectType}. Operations of type ${actionProjectType} are not allowed.` + }); + } + const rolePermissions = identityProjectPermission.roles?.map(({ role, permissions }) => ({ role, permissions })) || []; const additionalPrivileges = @@ -361,7 +376,8 @@ export const permissionServiceFactory = ({ const getServiceTokenProjectPermission = async ({ serviceTokenId, projectId, - actorOrgId + actorOrgId, + actionProjectType }: TGetServiceTokenProjectPermissionArg) => { const serviceToken = await serviceTokenDAL.findById(serviceTokenId); if (!serviceToken) throw new NotFoundError({ message: `Service token with ID '${serviceTokenId}' not found` }); @@ -386,6 +402,12 @@ export const permissionServiceFactory = ({ }); } + if (actionProjectType !== ActionProjectType.Any && actionProjectType !== serviceTokenProject.type) { + throw new BadRequestError({ + message: `The project is of type ${serviceTokenProject.type}. Operations of type ${actionProjectType} are not allowed.` + }); + } + const scopes = ServiceTokenScopes.parse(serviceToken.scopes || []); return { permission: buildServiceTokenProjectPermission(scopes, serviceToken.permissions), @@ -537,7 +559,8 @@ export const permissionServiceFactory = ({ actorId: inputActorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType }: TGetProjectPermissionArg): Promise> => { let actor = inputActor; let actorId = inputActorId; @@ -558,19 +581,22 @@ export const permissionServiceFactory = ({ userId: actorId, projectId, authMethod: actorAuthMethod, - userOrgId: actorOrgId + userOrgId: actorOrgId, + actionProjectType }) as Promise>; case ActorType.SERVICE: return getServiceTokenProjectPermission({ serviceTokenId: actorId, projectId, - actorOrgId + actorOrgId, + actionProjectType }) as Promise>; case ActorType.IDENTITY: return getIdentityProjectPermission({ identityId: actorId, projectId, - identityOrgId: actorOrgId + identityOrgId: actorOrgId, + actionProjectType }) as Promise>; default: throw new BadRequestError({ diff --git a/backend/src/ee/services/pit/pit-service.ts b/backend/src/ee/services/pit/pit-service.ts index c2a485b35..ef7f9b5a3 100644 --- a/backend/src/ee/services/pit/pit-service.ts +++ b/backend/src/ee/services/pit/pit-service.ts @@ -1,29 +1,53 @@ /* eslint-disable no-await-in-loop */ import { ForbiddenError } from "@casl/ability"; +import { ActionProjectType } from "@app/db/schemas"; +import { Event, EventType } from "@app/ee/services/audit-log/audit-log-types"; import { ProjectPermissionCommitsActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; -import { NotFoundError } from "@app/lib/errors"; +import { BadRequestError, NotFoundError } from "@app/lib/errors"; import { logger } from "@app/lib/logger"; import { ActorAuthMethod, ActorType } from "@app/services/auth/auth-type"; -import { ResourceType, TFolderCommitServiceFactory } from "@app/services/folder-commit/folder-commit-service"; +import { TFolderCommitDALFactory } from "@app/services/folder-commit/folder-commit-dal"; +import { + ResourceType, + TCommitResourceChangeDTO, + TFolderCommitServiceFactory +} from "@app/services/folder-commit/folder-commit-service"; import { isFolderCommitChange, isSecretCommitChange } from "@app/services/folder-commit-changes/folder-commit-changes-dal"; +import { TProjectDALFactory } from "@app/services/project/project-dal"; import { TProjectEnvDALFactory } from "@app/services/project-env/project-env-dal"; import { TSecretServiceFactory } from "@app/services/secret/secret-service"; +import { TProcessNewCommitRawDTO } from "@app/services/secret/secret-types"; import { TSecretFolderDALFactory } from "@app/services/secret-folder/secret-folder-dal"; import { TSecretFolderServiceFactory } from "@app/services/secret-folder/secret-folder-service"; +import { TSecretV2BridgeServiceFactory } from "@app/services/secret-v2-bridge/secret-v2-bridge-service"; +import { SecretOperations, SecretUpdateMode } from "@app/services/secret-v2-bridge/secret-v2-bridge-types"; import { TPermissionServiceFactory } from "../permission/permission-service-types"; +import { TSecretApprovalPolicyServiceFactory } from "../secret-approval-policy/secret-approval-policy-service"; +import { TSecretApprovalRequestServiceFactory } from "../secret-approval-request/secret-approval-request-service"; type TPitServiceFactoryDep = { folderCommitService: TFolderCommitServiceFactory; secretService: Pick; - folderService: Pick; + folderService: Pick< + TSecretFolderServiceFactory, + "getFolderById" | "getFolderVersions" | "createManyFolders" | "updateManyFolders" | "deleteManyFolders" + >; permissionService: Pick; - folderDAL: Pick; + folderDAL: Pick; projectEnvDAL: Pick; + secretApprovalRequestService: Pick< + TSecretApprovalRequestServiceFactory, + "generateSecretApprovalRequest" | "generateSecretApprovalRequestV2Bridge" + >; + secretApprovalPolicyService: Pick; + projectDAL: Pick; + secretV2BridgeService: TSecretV2BridgeServiceFactory; + folderCommitDAL: Pick; }; export type TPitServiceFactory = ReturnType; @@ -34,7 +58,12 @@ export const pitServiceFactory = ({ folderService, permissionService, folderDAL, - projectEnvDAL + projectEnvDAL, + secretApprovalRequestService, + secretApprovalPolicyService, + projectDAL, + secretV2BridgeService, + folderCommitDAL }: TPitServiceFactoryDep) => { const getCommitsCount = async ({ actor, @@ -320,7 +349,8 @@ export const pitServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(userPermission).throwUnlessCan( @@ -471,6 +501,347 @@ export const pitServiceFactory = ({ }); }; + const processNewCommitRaw = async ({ + actorId, + projectId, + environment, + actor, + actorOrgId, + actorAuthMethod, + secretPath, + message, + changes = { + secrets: { + create: [], + update: [], + delete: [] + }, + folders: { + create: [], + update: [], + delete: [] + } + } + }: { + actorId: string; + projectId: string; + environment: string; + actor: ActorType; + actorOrgId: string; + actorAuthMethod: ActorAuthMethod; + secretPath: string; + message: string; + changes: TProcessNewCommitRawDTO; + }) => { + const policy = + actor === ActorType.USER + ? await secretApprovalPolicyService.getSecretApprovalPolicy(projectId, environment, secretPath) + : undefined; + const secretMutationEvents: Event[] = []; + + const project = await projectDAL.findById(projectId); + if (project.enforceCapitalization) { + const caseViolatingSecretKeys = [ + // Check create operations + ...(changes.secrets?.create + ?.filter((sec) => sec.secretKey !== sec.secretKey.toUpperCase()) + .map((sec) => sec.secretKey) ?? []), + + // Check update operations + ...(changes.secrets?.update + ?.filter((sec) => sec.newSecretName && sec.newSecretName !== sec.newSecretName.toUpperCase()) + .map((sec) => sec.secretKey) ?? []) + ]; + + if (caseViolatingSecretKeys.length) { + throw new BadRequestError({ + message: `Secret names must be in UPPERCASE per project requirements: ${caseViolatingSecretKeys.join( + ", " + )}. You can disable this requirement in project settings` + }); + } + } + + const response = await folderCommitDAL.transaction(async (trx) => { + const targetFolder = await folderDAL.findBySecretPath(projectId, environment, secretPath, trx); + if (!targetFolder) + throw new NotFoundError({ + message: `Folder with path '${secretPath}' in environment with slug '${environment}' not found`, + name: "CreateManySecret" + }); + const commitChanges: TCommitResourceChangeDTO[] = []; + const folderChanges: { create: string[]; update: string[]; delete: string[] } = { + create: [], + update: [], + delete: [] + }; + + if ((changes.folders?.create?.length ?? 0) > 0) { + const createdFolders = await folderService.createManyFolders({ + projectId, + actor, + actorId, + actorOrgId, + actorAuthMethod, + folders: + changes.folders?.create?.map((folder) => ({ + name: folder.folderName, + environment, + path: secretPath, + description: folder.description + })) ?? [], + tx: trx, + commitChanges + }); + const newFolderEvents = createdFolders.folders.map( + (folder) => + ({ + type: EventType.CREATE_FOLDER, + metadata: { + environment, + folderId: folder.id, + folderName: folder.name, + folderPath: secretPath, + ...(folder.description ? { description: folder.description } : {}) + } + }) as Event + ); + secretMutationEvents.push(...newFolderEvents); + folderChanges.create.push(...createdFolders.folders.map((folder) => folder.id)); + } + + if ((changes.folders?.update?.length ?? 0) > 0) { + const updatedFolders = await folderService.updateManyFolders({ + projectId, + actor, + actorId, + actorOrgId, + actorAuthMethod, + folders: + changes.folders?.update?.map((folder) => ({ + environment, + path: secretPath, + id: folder.id, + name: folder.folderName, + description: folder.description + })) ?? [], + tx: trx, + commitChanges + }); + + const updatedFolderEvents = updatedFolders.newFolders.map( + (folder) => + ({ + type: EventType.UPDATE_FOLDER, + metadata: { + environment, + folderId: folder.id, + folderPath: secretPath, + newFolderName: folder.name, + newFolderDescription: folder.description + } + }) as Event + ); + secretMutationEvents.push(...updatedFolderEvents); + folderChanges.update.push(...updatedFolders.newFolders.map((folder) => folder.id)); + } + + if ((changes.folders?.delete?.length ?? 0) > 0) { + const deletedFolders = await folderService.deleteManyFolders({ + projectId, + actor, + actorId, + actorOrgId, + actorAuthMethod, + folders: + changes.folders?.delete?.map((folder) => ({ + environment, + path: secretPath, + idOrName: folder.id + })) ?? [], + tx: trx, + commitChanges + }); + const deletedFolderEvents = deletedFolders.folders.map( + (folder) => + ({ + type: EventType.DELETE_FOLDER, + metadata: { + environment, + folderId: folder.id, + folderPath: secretPath, + folderName: folder.name + } + }) as Event + ); + secretMutationEvents.push(...deletedFolderEvents); + folderChanges.delete.push(...deletedFolders.folders.map((folder) => folder.id)); + } + + if (policy) { + if ( + (changes.secrets?.create?.length ?? 0) > 0 || + (changes.secrets?.update?.length ?? 0) > 0 || + (changes.secrets?.delete?.length ?? 0) > 0 + ) { + const approval = await secretApprovalRequestService.generateSecretApprovalRequestV2Bridge({ + policy, + secretPath, + environment, + projectId, + actor, + actorId, + actorOrgId, + actorAuthMethod, + data: { + [SecretOperations.Create]: + changes.secrets?.create?.map((el) => ({ + tagIds: el.tagIds, + secretValue: el.secretValue, + secretComment: el.secretComment, + metadata: el.metadata, + skipMultilineEncoding: el.skipMultilineEncoding, + secretKey: el.secretKey, + secretMetadata: el.secretMetadata + })) ?? [], + [SecretOperations.Update]: + changes.secrets?.update?.map((el) => ({ + tagIds: el.tagIds, + newSecretName: el.newSecretName, + secretValue: el.secretValue, + secretComment: el.secretComment, + metadata: el.metadata, + skipMultilineEncoding: el.skipMultilineEncoding, + secretKey: el.secretKey, + secretMetadata: el.secretMetadata + })) ?? [], + [SecretOperations.Delete]: + changes.secrets?.delete?.map((el) => ({ + secretKey: el.secretKey + })) ?? [] + } + }); + return { + approvalId: approval.id, + folderChanges, + secretMutationEvents + }; + } + return { + folderChanges, + secretMutationEvents + }; + } + + if ((changes.secrets?.create?.length ?? 0) > 0) { + const newSecrets = await secretV2BridgeService.createManySecret({ + secretPath, + environment, + projectId, + actorAuthMethod, + actorOrgId, + actor, + actorId, + secrets: changes.secrets?.create ?? [], + tx: trx, + commitChanges + }); + secretMutationEvents.push({ + type: EventType.CREATE_SECRETS, + metadata: { + environment, + secretPath, + secrets: newSecrets.map((secret) => ({ + secretId: secret.id, + secretKey: secret.secretKey, + secretVersion: secret.version + })) + } + }); + } + if ((changes.secrets?.update?.length ?? 0) > 0) { + const updatedSecrets = await secretV2BridgeService.updateManySecret({ + secretPath, + environment, + projectId, + actorAuthMethod, + actorOrgId, + actor, + actorId, + secrets: changes.secrets?.update ?? [], + mode: SecretUpdateMode.FailOnNotFound, + tx: trx, + commitChanges + }); + secretMutationEvents.push({ + type: EventType.UPDATE_SECRETS, + metadata: { + environment, + secretPath, + secrets: updatedSecrets.map((secret) => ({ + secretId: secret.id, + secretKey: secret.secretKey, + secretVersion: secret.version + })) + } + }); + } + if ((changes.secrets?.delete?.length ?? 0) > 0) { + const deletedSecrets = await secretV2BridgeService.deleteManySecret({ + secretPath, + environment, + projectId, + actorAuthMethod, + actorOrgId, + actor, + actorId, + secrets: changes.secrets?.delete ?? [], + tx: trx, + commitChanges + }); + secretMutationEvents.push({ + type: EventType.DELETE_SECRETS, + metadata: { + environment, + secretPath, + secrets: deletedSecrets.map((secret) => ({ + secretId: secret.id, + secretKey: secret.secretKey, + secretVersion: secret.version + })) + } + }); + } + if (commitChanges?.length > 0) { + const commit = await folderCommitService.createCommit( + { + actor: { + type: actor || ActorType.PLATFORM, + metadata: { + id: actorId + } + }, + message, + folderId: targetFolder.id, + changes: commitChanges + }, + trx + ); + return { + folderChanges, + commitId: commit?.id, + secretMutationEvents + }; + } + return { + folderChanges, + secretMutationEvents + }; + }); + + return response; + }; + return { getCommitsCount, getCommitsForFolder, @@ -478,6 +849,7 @@ export const pitServiceFactory = ({ compareCommitChanges, rollbackToCommit, revertCommit, - getFolderStateAtCommit + getFolderStateAtCommit, + processNewCommitRaw }; }; diff --git a/backend/src/ee/services/project-template/project-template-fns.ts b/backend/src/ee/services/project-template/project-template-fns.ts index 5d4d0a953..8e8ebfa13 100644 --- a/backend/src/ee/services/project-template/project-template-fns.ts +++ b/backend/src/ee/services/project-template/project-template-fns.ts @@ -1,3 +1,4 @@ +import { ProjectType } from "@app/db/schemas"; import { InfisicalProjectTemplate, TUnpackedPermission @@ -6,18 +7,21 @@ import { getPredefinedRoles } from "@app/services/project-role/project-role-fns" import { ProjectTemplateDefaultEnvironments } from "./project-template-constants"; -export const getDefaultProjectTemplate = (orgId: string) => ({ +export const getDefaultProjectTemplate = (orgId: string, type: ProjectType) => ({ id: "b11b49a9-09a9-4443-916a-4246f9ff2c69", // random ID to appease zod + type, name: InfisicalProjectTemplate.Default, createdAt: new Date(), updatedAt: new Date(), - description: `Infisical's default project template`, - environments: ProjectTemplateDefaultEnvironments, - roles: getPredefinedRoles({ projectId: "project-template" }) as Array<{ - name: string; - slug: string; - permissions: TUnpackedPermission[]; - }>, + description: `Infisical's ${type} default project template`, + environments: type === ProjectType.SecretManager ? ProjectTemplateDefaultEnvironments : null, + roles: [...getPredefinedRoles({ projectId: "project-template", projectType: type })].map( + ({ name, slug, permissions }) => ({ + name, + slug, + permissions: permissions as TUnpackedPermission[] + }) + ), orgId }); diff --git a/backend/src/ee/services/project-template/project-template-service.ts b/backend/src/ee/services/project-template/project-template-service.ts index 510105572..f3fe07aa8 100644 --- a/backend/src/ee/services/project-template/project-template-service.ts +++ b/backend/src/ee/services/project-template/project-template-service.ts @@ -1,7 +1,7 @@ import { ForbiddenError } from "@casl/ability"; import { packRules } from "@casl/ability/extra"; -import { TProjectTemplates } from "@app/db/schemas"; +import { ProjectType, TProjectTemplates } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; @@ -29,11 +29,13 @@ const $unpackProjectTemplate = ({ roles, environments, ...rest }: TProjectTempla ...rest, environments: environments as TProjectTemplateEnvironment[], roles: [ - ...getPredefinedRoles({ projectId: "project-template" }).map(({ name, slug, permissions }) => ({ - name, - slug, - permissions: permissions as TUnpackedPermission[] - })), + ...getPredefinedRoles({ projectId: "project-template", projectType: rest.type as ProjectType }).map( + ({ name, slug, permissions }) => ({ + name, + slug, + permissions: permissions as TUnpackedPermission[] + }) + ), ...(roles as TProjectTemplateRole[]).map((role) => ({ ...role, permissions: unpackPermissions(role.permissions) @@ -46,7 +48,10 @@ export const projectTemplateServiceFactory = ({ permissionService, projectTemplateDAL }: TProjectTemplatesServiceFactoryDep): TProjectTemplateServiceFactory => { - const listProjectTemplatesByOrg: TProjectTemplateServiceFactory["listProjectTemplatesByOrg"] = async (actor) => { + const listProjectTemplatesByOrg: TProjectTemplateServiceFactory["listProjectTemplatesByOrg"] = async ( + actor, + type + ) => { const plan = await licenseService.getPlan(actor.orgId); if (!plan.projectTemplates) @@ -65,11 +70,14 @@ export const projectTemplateServiceFactory = ({ ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.ProjectTemplates); const projectTemplates = await projectTemplateDAL.find({ - orgId: actor.orgId + orgId: actor.orgId, + ...(type ? { type } : {}) }); return [ - getDefaultProjectTemplate(actor.orgId), + ...(type + ? [getDefaultProjectTemplate(actor.orgId, type)] + : Object.values(ProjectType).map((projectType) => getDefaultProjectTemplate(actor.orgId, projectType))), ...projectTemplates.map((template) => $unpackProjectTemplate(template)) ]; }; @@ -134,7 +142,7 @@ export const projectTemplateServiceFactory = ({ }; const createProjectTemplate: TProjectTemplateServiceFactory["createProjectTemplate"] = async ( - { roles, environments, ...params }, + { roles, environments, type, ...params }, actor ) => { const plan = await licenseService.getPlan(actor.orgId); @@ -154,6 +162,10 @@ export const projectTemplateServiceFactory = ({ ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.ProjectTemplates); + if (environments && type !== ProjectType.SecretManager) { + throw new BadRequestError({ message: "Cannot configure environments for non-SecretManager project templates" }); + } + if (environments && plan.environmentLimit !== null && environments.length > plan.environmentLimit) { throw new BadRequestError({ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions @@ -176,8 +188,10 @@ export const projectTemplateServiceFactory = ({ const projectTemplate = await projectTemplateDAL.create({ ...params, roles: JSON.stringify(roles.map((role) => ({ ...role, permissions: packRules(role.permissions) }))), - environments: environments ? JSON.stringify(environments ?? ProjectTemplateDefaultEnvironments) : null, - orgId: actor.orgId + environments: + type === ProjectType.SecretManager ? JSON.stringify(environments ?? ProjectTemplateDefaultEnvironments) : null, + orgId: actor.orgId, + type }); return $unpackProjectTemplate(projectTemplate); @@ -208,6 +222,11 @@ export const projectTemplateServiceFactory = ({ ); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.ProjectTemplates); + if (projectTemplate.type !== ProjectType.SecretManager && environments) + throw new BadRequestError({ message: "Cannot configure environments for non-SecretManager project templates" }); + + if (projectTemplate.type === ProjectType.SecretManager && environments === null) + throw new BadRequestError({ message: "Environments cannot be removed for SecretManager project templates" }); if (environments && plan.environmentLimit !== null && environments.length > plan.environmentLimit) { throw new BadRequestError({ diff --git a/backend/src/ee/services/project-template/project-template-types.ts b/backend/src/ee/services/project-template/project-template-types.ts index e705a096d..8d9e952a7 100644 --- a/backend/src/ee/services/project-template/project-template-types.ts +++ b/backend/src/ee/services/project-template/project-template-types.ts @@ -1,6 +1,6 @@ import { z } from "zod"; -import { ProjectMembershipRole, TProjectEnvironments } from "@app/db/schemas"; +import { ProjectMembershipRole, ProjectType, TProjectEnvironments } from "@app/db/schemas"; import { TProjectPermissionV2Schema } from "@app/ee/services/permission/project-permission"; import { OrgServiceActor } from "@app/lib/types"; import { UnpackedPermissionSchema } from "@app/server/routes/sanitizedSchema/permission"; @@ -15,6 +15,7 @@ export type TProjectTemplateRole = { export type TCreateProjectTemplateDTO = { name: string; + type: ProjectType; description?: string; roles: TProjectTemplateRole[]; environments?: TProjectTemplateEnvironment[] | null; @@ -29,11 +30,15 @@ export enum InfisicalProjectTemplate { } export type TProjectTemplateServiceFactory = { - listProjectTemplatesByOrg: (actor: OrgServiceActor) => Promise< + listProjectTemplatesByOrg: ( + actor: OrgServiceActor, + type?: ProjectType + ) => Promise< ( | { id: string; name: InfisicalProjectTemplate; + type: string; createdAt: Date; updatedAt: Date; description: string; @@ -58,6 +63,7 @@ export type TProjectTemplateServiceFactory = { } | { environments: TProjectTemplateEnvironment[]; + type: string; roles: { permissions: { action: string[]; @@ -94,6 +100,7 @@ export type TProjectTemplateServiceFactory = { }[]; name: string; orgId: string; + type: string; id: string; createdAt: Date; updatedAt: Date; @@ -118,6 +125,7 @@ export type TProjectTemplateServiceFactory = { name: string; orgId: string; id: string; + type: string; createdAt: Date; updatedAt: Date; description?: string | null | undefined; @@ -140,6 +148,7 @@ export type TProjectTemplateServiceFactory = { name: string; orgId: string; id: string; + type: string; createdAt: Date; updatedAt: Date; description?: string | null | undefined; @@ -162,6 +171,7 @@ export type TProjectTemplateServiceFactory = { }[]; name: string; orgId: string; + type: string; id: string; createdAt: Date; updatedAt: Date; @@ -184,6 +194,7 @@ export type TProjectTemplateServiceFactory = { name: string; }[]; name: string; + type: string; orgId: string; id: string; createdAt: Date; diff --git a/backend/src/ee/services/project-user-additional-privilege/project-user-additional-privilege-service.ts b/backend/src/ee/services/project-user-additional-privilege/project-user-additional-privilege-service.ts index d44ab054d..944775156 100644 --- a/backend/src/ee/services/project-user-additional-privilege/project-user-additional-privilege-service.ts +++ b/backend/src/ee/services/project-user-additional-privilege/project-user-additional-privilege-service.ts @@ -1,7 +1,7 @@ import { ForbiddenError, MongoAbility, RawRuleOf } from "@casl/ability"; import { PackRule, packRules, unpackRules } from "@casl/ability/extra"; -import { TableName } from "@app/db/schemas"; +import { ActionProjectType, TableName } from "@app/db/schemas"; import { BadRequestError, NotFoundError, PermissionBoundaryError } from "@app/lib/errors"; import { ms } from "@app/lib/ms"; import { validateHandlebarTemplate } from "@app/lib/template/validate-handlebars"; @@ -61,7 +61,8 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({ actorId, projectId: projectMembership.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionMemberActions.Edit, ProjectPermissionSub.Member); const { permission: targetUserPermission, membership } = await permissionService.getProjectPermission({ @@ -69,7 +70,8 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({ actorId: projectMembership.userId, projectId: projectMembership.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); // we need to validate that the privilege given is not higher than the assigning users permission @@ -164,7 +166,8 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({ actorId, projectId: projectMembership.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionMemberActions.Edit, ProjectPermissionSub.Member); const { permission: targetUserPermission } = await permissionService.getProjectPermission({ @@ -172,7 +175,8 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({ actorId: projectMembership.userId, projectId: projectMembership.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); // we need to validate that the privilege given is not higher than the assigning users permission @@ -272,7 +276,8 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({ actorId, projectId: projectMembership.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionMemberActions.Edit, ProjectPermissionSub.Member); @@ -317,7 +322,8 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({ actorId, projectId: projectMembership.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionMemberActions.Read, ProjectPermissionSub.Member); @@ -343,7 +349,8 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({ actorId, projectId: projectMembership.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionMemberActions.Read, ProjectPermissionSub.Member); diff --git a/backend/src/ee/services/secret-approval-policy/secret-approval-policy-service.ts b/backend/src/ee/services/secret-approval-policy/secret-approval-policy-service.ts index 80127c071..41a635e2f 100644 --- a/backend/src/ee/services/secret-approval-policy/secret-approval-policy-service.ts +++ b/backend/src/ee/services/secret-approval-policy/secret-approval-policy-service.ts @@ -1,6 +1,7 @@ import { ForbiddenError } from "@casl/ability"; import picomatch from "picomatch"; +import { ActionProjectType } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; @@ -110,7 +111,8 @@ export const secretApprovalPolicyServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Create, @@ -304,7 +306,8 @@ export const secretApprovalPolicyServiceFactory = ({ actorId, projectId: secretApprovalPolicy.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.SecretApproval); @@ -459,7 +462,8 @@ export const secretApprovalPolicyServiceFactory = ({ actorId, projectId: sapPolicy.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Delete, @@ -498,7 +502,8 @@ export const secretApprovalPolicyServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretApproval); @@ -542,7 +547,8 @@ export const secretApprovalPolicyServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); return getSecretApprovalPolicy(projectId, environment, secretPath); @@ -568,7 +574,8 @@ export const secretApprovalPolicyServiceFactory = ({ actorId, projectId: sapPolicy.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretApproval); diff --git a/backend/src/ee/services/secret-approval-request/secret-approval-request-fns.ts b/backend/src/ee/services/secret-approval-request/secret-approval-request-fns.ts index 5e4e0e3d6..dfe425b8e 100644 --- a/backend/src/ee/services/secret-approval-request/secret-approval-request-fns.ts +++ b/backend/src/ee/services/secret-approval-request/secret-approval-request-fns.ts @@ -36,7 +36,7 @@ export const sendApprovalEmailsFn = async ({ firstName: reviewerUser.firstName, projectName: project.name, organizationName: project.organization.name, - approvalUrl: `${cfg.SITE_URL}/projects/${project.id}/secret-manager/approval?requestId=${secretApprovalRequest.id}` + approvalUrl: `${cfg.SITE_URL}/projects/secret-management/${project.id}/approval?requestId=${secretApprovalRequest.id}` }, template: SmtpTemplates.SecretApprovalRequestNeedsReview }); diff --git a/backend/src/ee/services/secret-approval-request/secret-approval-request-service.ts b/backend/src/ee/services/secret-approval-request/secret-approval-request-service.ts index 2a755f9a6..2be0361e0 100644 --- a/backend/src/ee/services/secret-approval-request/secret-approval-request-service.ts +++ b/backend/src/ee/services/secret-approval-request/secret-approval-request-service.ts @@ -1,7 +1,9 @@ /* eslint-disable no-nested-ternary */ import { ForbiddenError, subject } from "@casl/ability"; +import { Knex } from "knex"; import { + ActionProjectType, ProjectMembershipRole, SecretEncryptionAlgo, SecretKeyEncoding, @@ -183,7 +185,8 @@ export const secretApprovalRequestServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const count = await secretApprovalRequestDAL.findProjectRequestCount(projectId, actorId, policyId); @@ -210,7 +213,8 @@ export const secretApprovalRequestServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const { shouldUseSecretV2Bridge } = await projectBotService.getBotKey(projectId); @@ -262,7 +266,8 @@ export const secretApprovalRequestServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); if ( !hasRole(ProjectMembershipRole.Admin) && @@ -411,7 +416,8 @@ export const secretApprovalRequestServiceFactory = ({ actorId, projectId: secretApprovalRequest.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); if ( !hasRole(ProjectMembershipRole.Admin) && @@ -480,7 +486,8 @@ export const secretApprovalRequestServiceFactory = ({ actorId, projectId: secretApprovalRequest.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); if ( !hasRole(ProjectMembershipRole.Admin) && @@ -536,7 +543,8 @@ export const secretApprovalRequestServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); if ( @@ -954,7 +962,7 @@ export const secretApprovalRequestServiceFactory = ({ bypassReason, secretPath: policy.secretPath, environment: env.name, - approvalUrl: `${cfg.SITE_URL}/projects/${project.id}/secret-manager/approval` + approvalUrl: `${cfg.SITE_URL}/projects/secret-management/${project.id}/approval` }, template: SmtpTemplates.AccessSecretRequestBypassed }); @@ -1088,7 +1096,8 @@ export const secretApprovalRequestServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, { @@ -1368,8 +1377,9 @@ export const secretApprovalRequestServiceFactory = ({ policy, projectId, secretPath, - environment - }: TGenerateSecretApprovalRequestV2BridgeDTO) => { + environment, + trx: providedTx + }: TGenerateSecretApprovalRequestV2BridgeDTO & { trx?: Knex }) => { if (actor === ActorType.SERVICE || actor === ActorType.Machine) throw new BadRequestError({ message: "Cannot use service token or machine token over protected branches" }); @@ -1378,7 +1388,8 @@ export const secretApprovalRequestServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath); if (!folder) @@ -1595,7 +1606,7 @@ export const secretApprovalRequestServiceFactory = ({ ); }); - const secretApprovalRequest = await secretApprovalRequestDAL.transaction(async (tx) => { + const executeApprovalRequestCreation = async (tx: Knex) => { const doc = await secretApprovalRequestDAL.create( { folderId, @@ -1657,7 +1668,11 @@ export const secretApprovalRequestServiceFactory = ({ } return { ...doc, commits: approvalCommits }; - }); + }; + + const secretApprovalRequest = providedTx + ? await executeApprovalRequestCreation(providedTx) + : await secretApprovalRequestDAL.transaction(executeApprovalRequestCreation); const user = await userDAL.findById(actorId); const env = await projectEnvDAL.findOne({ id: policy.envId }); diff --git a/backend/src/ee/services/secret-rotation-v2/okta-client-secret/index.ts b/backend/src/ee/services/secret-rotation-v2/okta-client-secret/index.ts new file mode 100644 index 000000000..8a1026194 --- /dev/null +++ b/backend/src/ee/services/secret-rotation-v2/okta-client-secret/index.ts @@ -0,0 +1,3 @@ +export * from "./okta-client-secret-rotation-constants"; +export * from "./okta-client-secret-rotation-schemas"; +export * from "./okta-client-secret-rotation-types"; diff --git a/backend/src/ee/services/secret-rotation-v2/okta-client-secret/okta-client-secret-rotation-constants.ts b/backend/src/ee/services/secret-rotation-v2/okta-client-secret/okta-client-secret-rotation-constants.ts new file mode 100644 index 000000000..35347f6b4 --- /dev/null +++ b/backend/src/ee/services/secret-rotation-v2/okta-client-secret/okta-client-secret-rotation-constants.ts @@ -0,0 +1,15 @@ +import { SecretRotation } from "@app/ee/services/secret-rotation-v2/secret-rotation-v2-enums"; +import { TSecretRotationV2ListItem } from "@app/ee/services/secret-rotation-v2/secret-rotation-v2-types"; +import { AppConnection } from "@app/services/app-connection/app-connection-enums"; + +export const OKTA_CLIENT_SECRET_ROTATION_LIST_OPTION: TSecretRotationV2ListItem = { + name: "Okta Client Secret", + type: SecretRotation.OktaClientSecret, + connection: AppConnection.Okta, + template: { + secretsMapping: { + clientId: "OKTA_CLIENT_ID", + clientSecret: "OKTA_CLIENT_SECRET" + } + } +}; diff --git a/backend/src/ee/services/secret-rotation-v2/okta-client-secret/okta-client-secret-rotation-fns.ts b/backend/src/ee/services/secret-rotation-v2/okta-client-secret/okta-client-secret-rotation-fns.ts new file mode 100644 index 000000000..0fe4438d1 --- /dev/null +++ b/backend/src/ee/services/secret-rotation-v2/okta-client-secret/okta-client-secret-rotation-fns.ts @@ -0,0 +1,273 @@ +/* eslint-disable no-await-in-loop */ +import { AxiosError } from "axios"; + +import { + TRotationFactory, + TRotationFactoryGetSecretsPayload, + TRotationFactoryIssueCredentials, + TRotationFactoryRevokeCredentials, + TRotationFactoryRotateCredentials +} from "@app/ee/services/secret-rotation-v2/secret-rotation-v2-types"; +import { request } from "@app/lib/config/request"; +import { delay as delayMs } from "@app/lib/delay"; +import { BadRequestError } from "@app/lib/errors"; +import { getOktaInstanceUrl } from "@app/services/app-connection/okta"; + +import { + TOktaClientSecret, + TOktaClientSecretRotationGeneratedCredentials, + TOktaClientSecretRotationWithConnection +} from "./okta-client-secret-rotation-types"; + +type OktaErrorResponse = { errorCode: string; errorSummary: string; errorCauses?: { errorSummary: string }[] }; + +const isOktaErrorResponse = (data: unknown): data is OktaErrorResponse => { + return ( + typeof data === "object" && + data !== null && + "errorSummary" in data && + typeof (data as OktaErrorResponse).errorSummary === "string" + ); +}; + +const createErrorMessage = (error: unknown) => { + if (error instanceof AxiosError) { + if (error.response?.data && isOktaErrorResponse(error.response.data)) { + const oktaError = error.response.data; + if (oktaError.errorCauses && oktaError.errorCauses.length > 0) { + return oktaError.errorCauses[0].errorSummary; + } + return oktaError.errorSummary; + } + if (error.message) { + return error.message; + } + } + return "Unknown error"; +}; + +// Delay between each revocation call in revokeCredentials +const DELAY_MS = 1000; + +export const oktaClientSecretRotationFactory: TRotationFactory< + TOktaClientSecretRotationWithConnection, + TOktaClientSecretRotationGeneratedCredentials +> = (secretRotation) => { + const { + connection, + parameters: { clientId }, + secretsMapping + } = secretRotation; + + /** + * Creates a new client secret for the Okta app. + */ + const $rotateClientSecret = async () => { + const instanceUrl = await getOktaInstanceUrl(connection); + + try { + const { data } = await request.post( + `${instanceUrl}/api/v1/apps/${clientId}/credentials/secrets`, + {}, + { + headers: { + Accept: "application/json", + Authorization: `SSWS ${connection.credentials.apiToken}` + } + } + ); + + if (!data.client_secret || !data.id) { + throw new Error("Invalid response from Okta: missing 'client_secret' or secret 'id'."); + } + + return { + clientSecret: data.client_secret, + secretId: data.id, + clientId + }; + } catch (error: unknown) { + if ( + error instanceof AxiosError && + error.response?.data && + isOktaErrorResponse(error.response.data) && + error.response.data.errorCode === "E0000001" + ) { + // Okta has a maximum of 2 secrets per app, thus we must warn the users in case they already have 2 + throw new BadRequestError({ + message: `Failed to add client secret to Okta app ${clientId}: You must have only a single secret for the Okta app prior to creating this secret rotation.` + }); + } + + throw new BadRequestError({ + message: `Failed to add client secret to Okta app ${clientId}: ${createErrorMessage(error)}` + }); + } + }; + + /** + * List client secrets. + */ + const $listClientSecrets = async () => { + const instanceUrl = await getOktaInstanceUrl(connection); + + try { + const { data } = await request.get( + `${instanceUrl}/api/v1/apps/${clientId}/credentials/secrets`, + { + headers: { + Accept: "application/json", + Authorization: `SSWS ${connection.credentials.apiToken}` + } + } + ); + + return data; + } catch (error: unknown) { + throw new BadRequestError({ + message: `Failed to list client secrets for Okta app ${clientId}: ${createErrorMessage(error)}` + }); + } + }; + + /** + * Checks if a credential with the given secretId exists. + */ + const credentialExists = async (secretId: string): Promise => { + const instanceUrl = await getOktaInstanceUrl(connection); + + try { + const { data } = await request.get( + `${instanceUrl}/api/v1/apps/${clientId}/credentials/secrets/${secretId}`, + { + headers: { + Accept: "application/json", + Authorization: `SSWS ${connection.credentials.apiToken}` + } + } + ); + + return data.id === secretId; + } catch (_) { + return false; + } + }; + + /** + * Revokes a client secret from the Okta app using its secretId. + * First checks if the credential exists before attempting revocation. + */ + const revokeCredential = async (secretId: string) => { + // Check if credential exists before attempting revocation + const exists = await credentialExists(secretId); + if (!exists) { + return; // Credential doesn't exist, nothing to revoke + } + + const instanceUrl = await getOktaInstanceUrl(connection); + + try { + // First deactivate the secret + await request.post( + `${instanceUrl}/api/v1/apps/${clientId}/credentials/secrets/${secretId}/lifecycle/deactivate`, + undefined, + { + headers: { + Authorization: `SSWS ${connection.credentials.apiToken}` + } + } + ); + + // Then delete it + await request.delete(`${instanceUrl}/api/v1/apps/${clientId}/credentials/secrets/${secretId}`, { + headers: { + Authorization: `SSWS ${connection.credentials.apiToken}` + } + }); + } catch (error: unknown) { + if ( + error instanceof AxiosError && + error.response?.data && + isOktaErrorResponse(error.response.data) && + error.response.data.errorCode === "E0000001" + ) { + // If this is the last secret, we cannot revoke it + return; + } + + throw new BadRequestError({ + message: `Failed to remove client secret with secretId ${secretId} from app ${clientId}: ${createErrorMessage(error)}` + }); + } + }; + + /** + * Issues a new set of credentials. + */ + const issueCredentials: TRotationFactoryIssueCredentials = async ( + callback + ) => { + const credentials = await $rotateClientSecret(); + return callback(credentials); + }; + + /** + * Revokes a list of credentials. + */ + const revokeCredentials: TRotationFactoryRevokeCredentials = async ( + credentials, + callback + ) => { + if (!credentials?.length) return callback(); + + for (const { secretId } of credentials) { + await revokeCredential(secretId); + await delayMs(DELAY_MS); + } + return callback(); + }; + + /** + * Rotates credentials by issuing new ones and revoking the old. + */ + const rotateCredentials: TRotationFactoryRotateCredentials = async ( + oldCredentials, + callback, + activeCredentials + ) => { + // Since in Okta you can only have a maximum of 2 secrets at a time, we must delete any other secret besides the current one PRIOR to generating the second secret + if (oldCredentials?.secretId) { + await revokeCredential(oldCredentials.secretId); + } else if (activeCredentials) { + // On the first rotation oldCredentials won't be set so we must find the second secret manually + const secrets = await $listClientSecrets(); + + if (secrets.length > 1) { + const nonActiveSecret = secrets.find((secret) => secret.id !== activeCredentials.secretId); + if (nonActiveSecret) { + await revokeCredential(nonActiveSecret.id); + } + } + } + + const newCredentials = await $rotateClientSecret(); + return callback(newCredentials); + }; + + /** + * Maps the generated credentials into the secret payload format. + */ + const getSecretsPayload: TRotationFactoryGetSecretsPayload = ({ + clientSecret + }) => [ + { key: secretsMapping.clientId, value: clientId }, + { key: secretsMapping.clientSecret, value: clientSecret } + ]; + + return { + issueCredentials, + revokeCredentials, + rotateCredentials, + getSecretsPayload + }; +}; diff --git a/backend/src/ee/services/secret-rotation-v2/okta-client-secret/okta-client-secret-rotation-schemas.ts b/backend/src/ee/services/secret-rotation-v2/okta-client-secret/okta-client-secret-rotation-schemas.ts new file mode 100644 index 000000000..9325d9518 --- /dev/null +++ b/backend/src/ee/services/secret-rotation-v2/okta-client-secret/okta-client-secret-rotation-schemas.ts @@ -0,0 +1,68 @@ +import { z } from "zod"; + +import { SecretRotation } from "@app/ee/services/secret-rotation-v2/secret-rotation-v2-enums"; +import { + BaseCreateSecretRotationSchema, + BaseSecretRotationSchema, + BaseUpdateSecretRotationSchema +} from "@app/ee/services/secret-rotation-v2/secret-rotation-v2-schemas"; +import { SecretRotations } from "@app/lib/api-docs"; +import { SecretNameSchema } from "@app/server/lib/schemas"; +import { AppConnection } from "@app/services/app-connection/app-connection-enums"; + +export const OktaClientSecretRotationGeneratedCredentialsSchema = z + .object({ + clientId: z.string(), + clientSecret: z.string(), + secretId: z.string() + }) + .array() + .min(1) + .max(2); + +const OktaClientSecretRotationParametersSchema = z.object({ + clientId: z + .string() + .trim() + .min(1, "Client ID Required") + .describe(SecretRotations.PARAMETERS.OKTA_CLIENT_SECRET.clientId) +}); + +const OktaClientSecretRotationSecretsMappingSchema = z.object({ + clientId: SecretNameSchema.describe(SecretRotations.SECRETS_MAPPING.OKTA_CLIENT_SECRET.clientId), + clientSecret: SecretNameSchema.describe(SecretRotations.SECRETS_MAPPING.OKTA_CLIENT_SECRET.clientSecret) +}); + +export const OktaClientSecretRotationTemplateSchema = z.object({ + secretsMapping: z.object({ + clientId: z.string(), + clientSecret: z.string() + }) +}); + +export const OktaClientSecretRotationSchema = BaseSecretRotationSchema(SecretRotation.OktaClientSecret).extend({ + type: z.literal(SecretRotation.OktaClientSecret), + parameters: OktaClientSecretRotationParametersSchema, + secretsMapping: OktaClientSecretRotationSecretsMappingSchema +}); + +export const CreateOktaClientSecretRotationSchema = BaseCreateSecretRotationSchema( + SecretRotation.OktaClientSecret +).extend({ + parameters: OktaClientSecretRotationParametersSchema, + secretsMapping: OktaClientSecretRotationSecretsMappingSchema +}); + +export const UpdateOktaClientSecretRotationSchema = BaseUpdateSecretRotationSchema( + SecretRotation.OktaClientSecret +).extend({ + parameters: OktaClientSecretRotationParametersSchema.optional(), + secretsMapping: OktaClientSecretRotationSecretsMappingSchema.optional() +}); + +export const OktaClientSecretRotationListItemSchema = z.object({ + name: z.literal("Okta Client Secret"), + connection: z.literal(AppConnection.Okta), + type: z.literal(SecretRotation.OktaClientSecret), + template: OktaClientSecretRotationTemplateSchema +}); diff --git a/backend/src/ee/services/secret-rotation-v2/okta-client-secret/okta-client-secret-rotation-types.ts b/backend/src/ee/services/secret-rotation-v2/okta-client-secret/okta-client-secret-rotation-types.ts new file mode 100644 index 000000000..101b4839e --- /dev/null +++ b/backend/src/ee/services/secret-rotation-v2/okta-client-secret/okta-client-secret-rotation-types.ts @@ -0,0 +1,40 @@ +import { z } from "zod"; + +import { TOktaConnection } from "@app/services/app-connection/okta"; + +import { + CreateOktaClientSecretRotationSchema, + OktaClientSecretRotationGeneratedCredentialsSchema, + OktaClientSecretRotationListItemSchema, + OktaClientSecretRotationSchema +} from "./okta-client-secret-rotation-schemas"; + +export type TOktaClientSecretRotation = z.infer; + +export type TOktaClientSecretRotationInput = z.infer; + +export type TOktaClientSecretRotationListItem = z.infer; + +export type TOktaClientSecretRotationWithConnection = TOktaClientSecretRotation & { + connection: TOktaConnection; +}; + +export type TOktaClientSecretRotationGeneratedCredentials = z.infer< + typeof OktaClientSecretRotationGeneratedCredentialsSchema +>; + +export interface TOktaClientSecretRotationParameters { + clientId: string; + secretId: string; +} + +export interface TOktaClientSecretRotationSecretsMapping { + clientId: string; + clientSecret: string; + secretId: string; +} + +export interface TOktaClientSecret { + id: string; + client_secret: string; +} diff --git a/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-enums.ts b/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-enums.ts index 84dc30821..cf0fe578a 100644 --- a/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-enums.ts +++ b/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-enums.ts @@ -6,7 +6,8 @@ export enum SecretRotation { Auth0ClientSecret = "auth0-client-secret", AzureClientSecret = "azure-client-secret", AwsIamUserSecret = "aws-iam-user-secret", - LdapPassword = "ldap-password" + LdapPassword = "ldap-password", + OktaClientSecret = "okta-client-secret" } export enum SecretRotationStatus { diff --git a/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-fns.ts b/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-fns.ts index 228c4c2a1..7c0239add 100644 --- a/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-fns.ts +++ b/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-fns.ts @@ -10,6 +10,7 @@ import { AZURE_CLIENT_SECRET_ROTATION_LIST_OPTION } from "./azure-client-secret" import { LDAP_PASSWORD_ROTATION_LIST_OPTION, TLdapPasswordRotation } from "./ldap-password"; import { MSSQL_CREDENTIALS_ROTATION_LIST_OPTION } from "./mssql-credentials"; import { MYSQL_CREDENTIALS_ROTATION_LIST_OPTION } from "./mysql-credentials"; +import { OKTA_CLIENT_SECRET_ROTATION_LIST_OPTION } from "./okta-client-secret"; import { ORACLEDB_CREDENTIALS_ROTATION_LIST_OPTION } from "./oracledb-credentials"; import { POSTGRES_CREDENTIALS_ROTATION_LIST_OPTION } from "./postgres-credentials"; import { SecretRotation, SecretRotationStatus } from "./secret-rotation-v2-enums"; @@ -30,7 +31,8 @@ const SECRET_ROTATION_LIST_OPTIONS: Record { diff --git a/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-maps.ts b/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-maps.ts index 029c9bdc5..d9a771101 100644 --- a/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-maps.ts +++ b/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-maps.ts @@ -9,7 +9,8 @@ export const SECRET_ROTATION_NAME_MAP: Record = { [SecretRotation.Auth0ClientSecret]: "Auth0 Client Secret", [SecretRotation.AzureClientSecret]: "Azure Client Secret", [SecretRotation.AwsIamUserSecret]: "AWS IAM User Secret", - [SecretRotation.LdapPassword]: "LDAP Password" + [SecretRotation.LdapPassword]: "LDAP Password", + [SecretRotation.OktaClientSecret]: "Okta Client Secret" }; export const SECRET_ROTATION_CONNECTION_MAP: Record = { @@ -20,5 +21,6 @@ export const SECRET_ROTATION_CONNECTION_MAP: Record; appConnectionDAL: Pick; folderCommitService: Pick; + gatewayService: Pick; }; export type TSecretRotationV2ServiceFactory = ReturnType; @@ -126,7 +129,8 @@ const SECRET_ROTATION_FACTORY_MAP: Record { const $queueSendSecretRotationStatusNotification = async (secretRotation: TSecretRotationV2Raw) => { const appCfg = getConfig(); @@ -218,7 +223,7 @@ export const secretRotationV2ServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretManager, projectId }); @@ -269,7 +274,7 @@ export const secretRotationV2ServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretManager, projectId }); @@ -315,7 +320,7 @@ export const secretRotationV2ServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretManager, projectId }); @@ -380,7 +385,7 @@ export const secretRotationV2ServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretManager, projectId }); @@ -424,7 +429,7 @@ export const secretRotationV2ServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretManager, projectId }); @@ -461,7 +466,8 @@ export const secretRotationV2ServiceFactory = ({ rotationInterval: payload.rotationInterval } as TSecretRotationV2WithConnection, appConnectionDAL, - kmsService + kmsService, + gatewayService ); // even though we have a db constraint we want to check before any rotation of credentials is attempted @@ -625,7 +631,7 @@ export const secretRotationV2ServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretManager, projectId }); @@ -775,7 +781,7 @@ export const secretRotationV2ServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretManager, projectId }); @@ -824,7 +830,8 @@ export const secretRotationV2ServiceFactory = ({ connection: appConnection } as TSecretRotationV2WithConnection, appConnectionDAL, - kmsService + kmsService, + gatewayService ); const generatedCredentials = await decryptSecretRotationCredentials({ @@ -907,7 +914,8 @@ export const secretRotationV2ServiceFactory = ({ connection: appConnection } as TSecretRotationV2WithConnection, appConnectionDAL, - kmsService + kmsService, + gatewayService ); const updatedRotation = await rotationFactory.rotateCredentials( @@ -1105,7 +1113,7 @@ export const secretRotationV2ServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretManager, projectId }); @@ -1152,7 +1160,7 @@ export const secretRotationV2ServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretManager, projectId }); @@ -1204,7 +1212,7 @@ export const secretRotationV2ServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretManager, projectId }); @@ -1320,7 +1328,8 @@ export const secretRotationV2ServiceFactory = ({ actorId: actor.id, projectId, actorAuthMethod: actor.authMethod, - actorOrgId: actor.orgId + actorOrgId: actor.orgId, + actionProjectType: ActionProjectType.SecretManager }); const permissiveFolderMappings = folderMappings.filter(({ path, environment }) => diff --git a/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-types.ts b/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-types.ts index 5547d4582..ab348f172 100644 --- a/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-types.ts +++ b/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-types.ts @@ -1,4 +1,5 @@ import { AuditLogInfo } from "@app/ee/services/audit-log/audit-log-types"; +import { TGatewayServiceFactory } from "@app/ee/services/gateway/gateway-service"; import { TSqlCredentialsRotationGeneratedCredentials } from "@app/ee/services/secret-rotation-v2/shared/sql-credentials/sql-credentials-rotation-types"; import { OrderByDirection } from "@app/lib/types"; import { TAppConnectionDALFactory } from "@app/services/app-connection/app-connection-dal"; @@ -45,6 +46,13 @@ import { TMySqlCredentialsRotationListItem, TMySqlCredentialsRotationWithConnection } from "./mysql-credentials"; +import { + TOktaClientSecretRotation, + TOktaClientSecretRotationGeneratedCredentials, + TOktaClientSecretRotationInput, + TOktaClientSecretRotationListItem, + TOktaClientSecretRotationWithConnection +} from "./okta-client-secret"; import { TOracleDBCredentialsRotation, TOracleDBCredentialsRotationInput, @@ -68,7 +76,8 @@ export type TSecretRotationV2 = | TAuth0ClientSecretRotation | TAzureClientSecretRotation | TLdapPasswordRotation - | TAwsIamUserSecretRotation; + | TAwsIamUserSecretRotation + | TOktaClientSecretRotation; export type TSecretRotationV2WithConnection = | TPostgresCredentialsRotationWithConnection @@ -78,14 +87,16 @@ export type TSecretRotationV2WithConnection = | TAuth0ClientSecretRotationWithConnection | TAzureClientSecretRotationWithConnection | TLdapPasswordRotationWithConnection - | TAwsIamUserSecretRotationWithConnection; + | TAwsIamUserSecretRotationWithConnection + | TOktaClientSecretRotationWithConnection; export type TSecretRotationV2GeneratedCredentials = | TSqlCredentialsRotationGeneratedCredentials | TAuth0ClientSecretRotationGeneratedCredentials | TAzureClientSecretRotationGeneratedCredentials | TLdapPasswordRotationGeneratedCredentials - | TAwsIamUserSecretRotationGeneratedCredentials; + | TAwsIamUserSecretRotationGeneratedCredentials + | TOktaClientSecretRotationGeneratedCredentials; export type TSecretRotationV2Input = | TPostgresCredentialsRotationInput @@ -95,7 +106,8 @@ export type TSecretRotationV2Input = | TAuth0ClientSecretRotationInput | TAzureClientSecretRotationInput | TLdapPasswordRotationInput - | TAwsIamUserSecretRotationInput; + | TAwsIamUserSecretRotationInput + | TOktaClientSecretRotationInput; export type TSecretRotationV2ListItem = | TPostgresCredentialsRotationListItem @@ -105,7 +117,8 @@ export type TSecretRotationV2ListItem = | TAuth0ClientSecretRotationListItem | TAzureClientSecretRotationListItem | TLdapPasswordRotationListItem - | TAwsIamUserSecretRotationListItem; + | TAwsIamUserSecretRotationListItem + | TOktaClientSecretRotationListItem; export type TSecretRotationV2TemporaryParameters = TLdapPasswordRotationInput["temporaryParameters"] | undefined; @@ -239,7 +252,8 @@ export type TRotationFactory< > = ( secretRotation: T, appConnectionDAL: Pick, - kmsService: Pick + kmsService: Pick, + gatewayService: Pick ) => { issueCredentials: TRotationFactoryIssueCredentials; revokeCredentials: TRotationFactoryRevokeCredentials; diff --git a/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-union-schema.ts b/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-union-schema.ts index 6dd04d47e..ce5f10bc4 100644 --- a/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-union-schema.ts +++ b/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-union-schema.ts @@ -6,6 +6,7 @@ import { AzureClientSecretRotationSchema } from "@app/ee/services/secret-rotatio import { LdapPasswordRotationSchema } from "@app/ee/services/secret-rotation-v2/ldap-password"; import { MsSqlCredentialsRotationSchema } from "@app/ee/services/secret-rotation-v2/mssql-credentials"; import { MySqlCredentialsRotationSchema } from "@app/ee/services/secret-rotation-v2/mysql-credentials"; +import { OktaClientSecretRotationSchema } from "@app/ee/services/secret-rotation-v2/okta-client-secret"; import { OracleDBCredentialsRotationSchema } from "@app/ee/services/secret-rotation-v2/oracledb-credentials"; import { PostgresCredentialsRotationSchema } from "@app/ee/services/secret-rotation-v2/postgres-credentials"; @@ -17,5 +18,6 @@ export const SecretRotationV2Schema = z.discriminatedUnion("type", [ Auth0ClientSecretRotationSchema, AzureClientSecretRotationSchema, LdapPasswordRotationSchema, - AwsIamUserSecretRotationSchema + AwsIamUserSecretRotationSchema, + OktaClientSecretRotationSchema ]); diff --git a/backend/src/ee/services/secret-rotation-v2/shared/sql-credentials/sql-credentials-rotation-fns.ts b/backend/src/ee/services/secret-rotation-v2/shared/sql-credentials/sql-credentials-rotation-fns.ts index 12e9b5964..3e6e5d265 100644 --- a/backend/src/ee/services/secret-rotation-v2/shared/sql-credentials/sql-credentials-rotation-fns.ts +++ b/backend/src/ee/services/secret-rotation-v2/shared/sql-credentials/sql-credentials-rotation-fns.ts @@ -1,3 +1,5 @@ +import { Knex } from "knex"; + import { TRotationFactory, TRotationFactoryGetSecretsPayload, @@ -5,7 +7,10 @@ import { TRotationFactoryRevokeCredentials, TRotationFactoryRotateCredentials } from "@app/ee/services/secret-rotation-v2/secret-rotation-v2-types"; -import { getSqlConnectionClient, SQL_CONNECTION_ALTER_LOGIN_STATEMENT } from "@app/services/app-connection/shared/sql"; +import { + executeWithPotentialGateway, + SQL_CONNECTION_ALTER_LOGIN_STATEMENT +} from "@app/services/app-connection/shared/sql"; import { generatePassword } from "../utils"; import { @@ -30,7 +35,7 @@ const redactPasswords = (e: unknown, credentials: TSqlCredentialsRotationGenerat export const sqlCredentialsRotationFactory: TRotationFactory< TSqlCredentialsRotationWithConnection, TSqlCredentialsRotationGeneratedCredentials -> = (secretRotation) => { +> = (secretRotation, _appConnectionDAL, _kmsService, gatewayService) => { const { connection, parameters: { username1, username2 }, @@ -38,29 +43,38 @@ export const sqlCredentialsRotationFactory: TRotationFactory< secretsMapping } = secretRotation; - const $validateCredentials = async (credentials: TSqlCredentialsRotationGeneratedCredentials[number]) => { - const client = await getSqlConnectionClient({ - ...connection, - credentials: { - ...connection.credentials, - ...credentials - } - }); + const executeOperation = ( + operation: (client: Knex) => Promise, + credentialsOverride?: TSqlCredentialsRotationGeneratedCredentials[number] + ) => { + const finalCredentials = { + ...connection.credentials, + ...credentialsOverride + }; + return executeWithPotentialGateway( + { + ...connection, + credentials: finalCredentials + }, + gatewayService, + (client) => operation(client) + ); + }; + + const $validateCredentials = async (credentials: TSqlCredentialsRotationGeneratedCredentials[number]) => { try { - await client.raw("SELECT 1"); + await executeOperation(async (client) => { + await client.raw("SELECT 1"); + }, credentials); } catch (error) { throw new Error(redactPasswords(error, [credentials])); - } finally { - await client.destroy(); } }; const issueCredentials: TRotationFactoryIssueCredentials = async ( callback ) => { - const client = await getSqlConnectionClient(connection); - // For SQL, since we get existing users, we change both their passwords // on issue to invalidate their existing passwords const credentialsSet = [ @@ -69,15 +83,15 @@ export const sqlCredentialsRotationFactory: TRotationFactory< ]; try { - await client.transaction(async (tx) => { - for await (const credentials of credentialsSet) { - await tx.raw(...SQL_CONNECTION_ALTER_LOGIN_STATEMENT[connection.app](credentials)); - } + await executeOperation(async (client) => { + await client.transaction(async (tx) => { + for await (const credentials of credentialsSet) { + await tx.raw(...SQL_CONNECTION_ALTER_LOGIN_STATEMENT[connection.app](credentials)); + } + }); }); } catch (error) { throw new Error(redactPasswords(error, credentialsSet)); - } finally { - await client.destroy(); } for await (const credentials of credentialsSet) { @@ -91,21 +105,19 @@ export const sqlCredentialsRotationFactory: TRotationFactory< credentialsToRevoke, callback ) => { - const client = await getSqlConnectionClient(connection); - const revokedCredentials = credentialsToRevoke.map(({ username }) => ({ username, password: generatePassword() })); try { - await client.transaction(async (tx) => { - for await (const credentials of revokedCredentials) { - // invalidate previous passwords - await tx.raw(...SQL_CONNECTION_ALTER_LOGIN_STATEMENT[connection.app](credentials)); - } + await executeOperation(async (client) => { + await client.transaction(async (tx) => { + for await (const credentials of revokedCredentials) { + // invalidate previous passwords + await tx.raw(...SQL_CONNECTION_ALTER_LOGIN_STATEMENT[connection.app](credentials)); + } + }); }); } catch (error) { throw new Error(redactPasswords(error, revokedCredentials)); - } finally { - await client.destroy(); } return callback(); @@ -115,17 +127,15 @@ export const sqlCredentialsRotationFactory: TRotationFactory< _, callback ) => { - const client = await getSqlConnectionClient(connection); - // generate new password for the next active user const credentials = { username: activeIndex === 0 ? username2 : username1, password: generatePassword() }; try { - await client.raw(...SQL_CONNECTION_ALTER_LOGIN_STATEMENT[connection.app](credentials)); + await executeOperation(async (client) => { + await client.raw(...SQL_CONNECTION_ALTER_LOGIN_STATEMENT[connection.app](credentials)); + }); } catch (error) { throw new Error(redactPasswords(error, [credentials])); - } finally { - await client.destroy(); } await $validateCredentials(credentials); diff --git a/backend/src/ee/services/secret-rotation/secret-rotation-service.ts b/backend/src/ee/services/secret-rotation/secret-rotation-service.ts index 53056e294..04ece7e5b 100644 --- a/backend/src/ee/services/secret-rotation/secret-rotation-service.ts +++ b/backend/src/ee/services/secret-rotation/secret-rotation-service.ts @@ -1,7 +1,7 @@ import { ForbiddenError, subject } from "@casl/ability"; import Ajv from "ajv"; -import { ProjectVersion, TableName } from "@app/db/schemas"; +import { ActionProjectType, ProjectVersion, TableName } from "@app/db/schemas"; import { crypto, SymmetricKeySize } from "@app/lib/crypto/cryptography"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; import { TProjectPermission } from "@app/lib/types"; @@ -66,7 +66,8 @@ export const secretRotationServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionSecretRotationActions.Read, @@ -97,7 +98,8 @@ export const secretRotationServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionSecretRotationActions.Read, @@ -213,7 +215,8 @@ export const secretRotationServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionSecretRotationActions.Read, @@ -263,7 +266,8 @@ export const secretRotationServiceFactory = ({ actorId, projectId: project.id, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionSecretRotationActions.Edit, @@ -283,7 +287,8 @@ export const secretRotationServiceFactory = ({ actorId, projectId: doc.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionSecretRotationActions.Delete, diff --git a/backend/src/ee/services/secret-scanning-v2/secret-scanning-v2-queue.ts b/backend/src/ee/services/secret-scanning-v2/secret-scanning-v2-queue.ts index 137034feb..1550ef41a 100644 --- a/backend/src/ee/services/secret-scanning-v2/secret-scanning-v2-queue.ts +++ b/backend/src/ee/services/secret-scanning-v2/secret-scanning-v2-queue.ts @@ -567,14 +567,18 @@ export const secretScanningV2QueueServiceFactory = async ({ const projectMembers = await projectMembershipDAL.findAllProjectMembers(projectId); const project = await projectDAL.findById(projectId); - const projectAdmins = projectMembers.filter((member) => - member.roles.some((role) => role.role === ProjectMembershipRole.Admin) - ); + const recipients = projectMembers.filter((member) => { + const isAdmin = member.roles.some((role) => role.role === ProjectMembershipRole.Admin); + const isCompleted = payload.status === SecretScanningScanStatus.Completed; + // We assume that the committer is one of the project members + const isCommitter = isCompleted && payload.authorEmail === member.user.email; + return isAdmin || isCommitter; + }); const timestamp = new Date().toISOString(); await smtpService.sendMail({ - recipients: projectAdmins.map((member) => member.user.email!).filter(Boolean), + recipients: recipients.map((member) => member.user.email!).filter(Boolean), template: payload.status === SecretScanningScanStatus.Completed ? SmtpTemplates.SecretScanningV2SecretsDetected diff --git a/backend/src/ee/services/secret-scanning-v2/secret-scanning-v2-service.ts b/backend/src/ee/services/secret-scanning-v2/secret-scanning-v2-service.ts index 761059d2a..41da217d8 100644 --- a/backend/src/ee/services/secret-scanning-v2/secret-scanning-v2-service.ts +++ b/backend/src/ee/services/secret-scanning-v2/secret-scanning-v2-service.ts @@ -1,6 +1,7 @@ import { ForbiddenError } from "@casl/ability"; import { join } from "path"; +import { ActionProjectType } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { @@ -94,7 +95,7 @@ export const secretScanningV2ServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretScanning, projectId }); @@ -156,7 +157,7 @@ export const secretScanningV2ServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretScanning, projectId: dataSource.projectId }); @@ -201,7 +202,7 @@ export const secretScanningV2ServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretScanning, projectId }); @@ -235,7 +236,7 @@ export const secretScanningV2ServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretScanning, projectId: payload.projectId }); @@ -348,7 +349,7 @@ export const secretScanningV2ServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretScanning, projectId: dataSource.projectId }); @@ -401,6 +402,7 @@ export const secretScanningV2ServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, + actionProjectType: ActionProjectType.SecretScanning, projectId: dataSource.projectId }); @@ -474,7 +476,7 @@ export const secretScanningV2ServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretScanning, projectId: dataSource.projectId }); @@ -538,7 +540,7 @@ export const secretScanningV2ServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretScanning, projectId: dataSource.projectId }); @@ -583,7 +585,7 @@ export const secretScanningV2ServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretScanning, projectId: dataSource.projectId }); @@ -626,7 +628,7 @@ export const secretScanningV2ServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretScanning, projectId: dataSource.projectId }); @@ -669,7 +671,7 @@ export const secretScanningV2ServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretScanning, projectId: dataSource.projectId }); @@ -702,7 +704,7 @@ export const secretScanningV2ServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretScanning, projectId }); @@ -736,7 +738,7 @@ export const secretScanningV2ServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretScanning, projectId }); @@ -776,7 +778,7 @@ export const secretScanningV2ServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretScanning, projectId: finding.projectId }); @@ -807,7 +809,7 @@ export const secretScanningV2ServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretScanning, projectId }); @@ -842,7 +844,7 @@ export const secretScanningV2ServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretScanning, projectId }); diff --git a/backend/src/ee/services/secret-snapshot/secret-snapshot-service.ts b/backend/src/ee/services/secret-snapshot/secret-snapshot-service.ts index a61b0d586..d60f0f0a0 100644 --- a/backend/src/ee/services/secret-snapshot/secret-snapshot-service.ts +++ b/backend/src/ee/services/secret-snapshot/secret-snapshot-service.ts @@ -2,7 +2,7 @@ // akhilmhdh: I did this, quite strange bug with eslint. Everything do have a type stil has this error import { ForbiddenError } from "@casl/ability"; -import { TableName, TSecretTagJunctionInsert, TSecretV2TagJunctionInsert } from "@app/db/schemas"; +import { ActionProjectType, TableName, TSecretTagJunctionInsert, TSecretV2TagJunctionInsert } from "@app/db/schemas"; import { crypto, SymmetricKeySize } from "@app/lib/crypto/cryptography"; import { InternalServerError, NotFoundError } from "@app/lib/errors"; import { groupBy } from "@app/lib/fn"; @@ -103,7 +103,8 @@ export const secretSnapshotServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback); @@ -139,7 +140,8 @@ export const secretSnapshotServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback); @@ -167,7 +169,8 @@ export const secretSnapshotServiceFactory = ({ actorId, projectId: snapshot.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback); @@ -391,7 +394,8 @@ export const secretSnapshotServiceFactory = ({ actorId, projectId: snapshot.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Create, diff --git a/backend/src/ee/services/ssh-certificate-template/ssh-certificate-template-service.ts b/backend/src/ee/services/ssh-certificate-template/ssh-certificate-template-service.ts index e679fdfac..49d8c1ab6 100644 --- a/backend/src/ee/services/ssh-certificate-template/ssh-certificate-template-service.ts +++ b/backend/src/ee/services/ssh-certificate-template/ssh-certificate-template-service.ts @@ -1,5 +1,6 @@ import { ForbiddenError } from "@casl/ability"; +import { ActionProjectType } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; @@ -58,7 +59,8 @@ export const sshCertificateTemplateServiceFactory = ({ actorId, projectId: ca.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan( @@ -130,7 +132,8 @@ export const sshCertificateTemplateServiceFactory = ({ actorId, projectId: certTemplate.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan( @@ -198,7 +201,8 @@ export const sshCertificateTemplateServiceFactory = ({ actorId, projectId: certificateTemplate.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan( @@ -224,7 +228,8 @@ export const sshCertificateTemplateServiceFactory = ({ actorId, projectId: certTemplate.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan( diff --git a/backend/src/ee/services/ssh-host-group/ssh-host-group-service.ts b/backend/src/ee/services/ssh-host-group/ssh-host-group-service.ts index fba849d93..aa6d4f66a 100644 --- a/backend/src/ee/services/ssh-host-group/ssh-host-group-service.ts +++ b/backend/src/ee/services/ssh-host-group/ssh-host-group-service.ts @@ -1,5 +1,6 @@ import { ForbiddenError } from "@casl/ability"; +import { ActionProjectType } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { TSshHostDALFactory } from "@app/ee/services/ssh-host/ssh-host-dal"; @@ -79,7 +80,8 @@ export const sshHostGroupServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.SshHostGroups); @@ -171,7 +173,8 @@ export const sshHostGroupServiceFactory = ({ actorId, projectId: sshHostGroup.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.SshHostGroups); @@ -267,7 +270,8 @@ export const sshHostGroupServiceFactory = ({ actorId, projectId: sshHostGroup.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SshHostGroups); @@ -290,7 +294,8 @@ export const sshHostGroupServiceFactory = ({ actorId, projectId: sshHostGroup.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.SshHostGroups); @@ -316,7 +321,8 @@ export const sshHostGroupServiceFactory = ({ actorId, projectId: sshHostGroup.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SshHostGroups); @@ -354,7 +360,8 @@ export const sshHostGroupServiceFactory = ({ actorId, projectId: sshHostGroup.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.SshHostGroups); @@ -393,7 +400,8 @@ export const sshHostGroupServiceFactory = ({ actorId, projectId: sshHostGroup.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.SshHostGroups); diff --git a/backend/src/ee/services/ssh-host/ssh-host-fns.ts b/backend/src/ee/services/ssh-host/ssh-host-fns.ts index 5b2f98728..dec15e093 100644 --- a/backend/src/ee/services/ssh-host/ssh-host-fns.ts +++ b/backend/src/ee/services/ssh-host/ssh-host-fns.ts @@ -1,5 +1,6 @@ import { Knex } from "knex"; +import { ActionProjectType } from "@app/db/schemas"; import { BadRequestError } from "@app/lib/errors"; import { ProjectPermissionSshHostActions, ProjectPermissionSub } from "../permission/project-permission"; @@ -62,7 +63,8 @@ export const createSshLoginMappings = async ({ userId: user.id, projectId, authMethod: actorAuthMethod, - userOrgId: actorOrgId + userOrgId: actorOrgId, + actionProjectType: ActionProjectType.SSH }); } diff --git a/backend/src/ee/services/ssh-host/ssh-host-service.ts b/backend/src/ee/services/ssh-host/ssh-host-service.ts index 36bc1bbb3..d1082b4df 100644 --- a/backend/src/ee/services/ssh-host/ssh-host-service.ts +++ b/backend/src/ee/services/ssh-host/ssh-host-service.ts @@ -1,5 +1,6 @@ import { ForbiddenError, subject } from "@casl/ability"; +import { ActionProjectType } from "@app/db/schemas"; import { TGroupDALFactory } from "@app/ee/services/group/group-dal"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionSshHostActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; @@ -111,7 +112,8 @@ export const sshHostServiceFactory = ({ actorId, projectId: project.id, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); const projectHosts = await sshHostDAL.findUserAccessibleSshHosts([project.id], actorId); @@ -144,7 +146,8 @@ export const sshHostServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan( @@ -273,7 +276,8 @@ export const sshHostServiceFactory = ({ actorId, projectId: host.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan( @@ -334,7 +338,8 @@ export const sshHostServiceFactory = ({ actorId, projectId: host.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan( @@ -362,7 +367,8 @@ export const sshHostServiceFactory = ({ actorId, projectId: host.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan( @@ -401,7 +407,8 @@ export const sshHostServiceFactory = ({ actorId, projectId: host.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); const internalPrincipals = await convertActorToPrincipals({ @@ -520,7 +527,8 @@ export const sshHostServiceFactory = ({ actorId, projectId: host.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan( diff --git a/backend/src/ee/services/ssh/ssh-certificate-authority-service.ts b/backend/src/ee/services/ssh/ssh-certificate-authority-service.ts index 2e45c836d..6c35f0ddd 100644 --- a/backend/src/ee/services/ssh/ssh-certificate-authority-service.ts +++ b/backend/src/ee/services/ssh/ssh-certificate-authority-service.ts @@ -1,5 +1,6 @@ import { ForbiddenError } from "@casl/ability"; +import { ActionProjectType } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { TSshCertificateAuthorityDALFactory } from "@app/ee/services/ssh/ssh-certificate-authority-dal"; @@ -72,7 +73,8 @@ export const sshCertificateAuthorityServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan( @@ -107,7 +109,8 @@ export const sshCertificateAuthorityServiceFactory = ({ actorId, projectId: ca.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan( @@ -175,7 +178,8 @@ export const sshCertificateAuthorityServiceFactory = ({ actorId, projectId: ca.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan( @@ -213,7 +217,8 @@ export const sshCertificateAuthorityServiceFactory = ({ actorId, projectId: ca.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan( @@ -254,7 +259,8 @@ export const sshCertificateAuthorityServiceFactory = ({ actorId, projectId: sshCertificateTemplate.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan( @@ -375,7 +381,8 @@ export const sshCertificateAuthorityServiceFactory = ({ actorId, projectId: sshCertificateTemplate.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan( @@ -472,7 +479,8 @@ export const sshCertificateAuthorityServiceFactory = ({ actorId, projectId: ca.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan( diff --git a/backend/src/ee/services/trusted-ip/trusted-ip-service.ts b/backend/src/ee/services/trusted-ip/trusted-ip-service.ts index 69e7e5e1d..6b9686e25 100644 --- a/backend/src/ee/services/trusted-ip/trusted-ip-service.ts +++ b/backend/src/ee/services/trusted-ip/trusted-ip-service.ts @@ -1,5 +1,6 @@ import { ForbiddenError } from "@casl/ability"; +import { ActionProjectType } from "@app/db/schemas"; import { BadRequestError } from "@app/lib/errors"; import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip"; import { TProjectDALFactory } from "@app/services/project/project-dal"; @@ -35,7 +36,8 @@ export const trustedIpServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.IpAllowList); const trustedIps = await trustedIpDAL.find({ @@ -59,7 +61,8 @@ export const trustedIpServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.IpAllowList); @@ -104,7 +107,8 @@ export const trustedIpServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.IpAllowList); @@ -149,7 +153,8 @@ export const trustedIpServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.IpAllowList); diff --git a/backend/src/lib/api-docs/constants.ts b/backend/src/lib/api-docs/constants.ts index 584f480ad..ac4ee26fb 100644 --- a/backend/src/lib/api-docs/constants.ts +++ b/backend/src/lib/api-docs/constants.ts @@ -2289,6 +2289,10 @@ export const AppConnections = { SUPABASE: { accessKey: "The Key used to access Supabase.", instanceUrl: "The URL used to access Supabase." + }, + OKTA: { + instanceUrl: "The URL used to access your Okta organization.", + apiToken: "The API token used to authenticate with Okta." } } }; @@ -2502,6 +2506,11 @@ export const SecretSyncs = { SUPABASE: { projectId: "The ID of the Supabase project to sync secrets to.", projectName: "The name of the Supabase project to sync secrets to." + }, + BITBUCKET: { + workspaceSlug: "The Bitbucket Workspace slug to sync secrets to.", + repositorySlug: "The Bitbucket Repository slug to sync secrets to.", + environmentId: "The Bitbucket Deployment Environment uuid to sync secrets to." } } }; @@ -2594,6 +2603,9 @@ export const SecretRotations = { AWS_IAM_USER_SECRET: { userName: "The name of the client to rotate credentials for.", region: "The AWS region the client is present in." + }, + OKTA_CLIENT_SECRET: { + clientId: "The ID of the Okta Application to rotate the client secret for." } }, SECRETS_MAPPING: { @@ -2616,6 +2628,10 @@ export const SecretRotations = { AWS_IAM_USER_SECRET: { accessKeyId: "The name of the secret that the access key ID will be mapped to.", secretAccessKey: "The name of the secret that the rotated secret access key will be mapped to." + }, + OKTA_CLIENT_SECRET: { + clientId: "The name of the secret that the client ID will be mapped to.", + clientSecret: "The name of the secret that the rotated client secret will be mapped to." } } }; diff --git a/backend/src/lib/crypto/cryptography/crypto.ts b/backend/src/lib/crypto/cryptography/crypto.ts index 9a986efbb..967e7e007 100644 --- a/backend/src/lib/crypto/cryptography/crypto.ts +++ b/backend/src/lib/crypto/cryptography/crypto.ts @@ -93,7 +93,13 @@ const cryptographyFactory = () => { }; const verifyFipsLicense = (licenseService: Pick) => { - if (isFipsModeEnabled({ skipInitializationCheck: true }) && !licenseService.onPremFeatures?.fips) { + const appCfg = getConfig(); + + if ( + !appCfg.isDevelopmentMode && + isFipsModeEnabled({ skipInitializationCheck: true }) && + !licenseService.onPremFeatures?.fips + ) { throw new CryptographyError({ message: "FIPS mode is enabled but your license does not include FIPS support. Please contact support." }); diff --git a/backend/src/server/lib/cookie.ts b/backend/src/server/lib/cookie.ts index cc6956056..323bf4be9 100644 --- a/backend/src/server/lib/cookie.ts +++ b/backend/src/server/lib/cookie.ts @@ -3,6 +3,11 @@ import { FastifyReply } from "fastify"; import { getConfig } from "@app/lib/config/env"; import { logger } from "@app/lib/logger"; +/** + * `aod` (Auth Origin Domain) cookie is used to store the origin domain of the application when user was last authenticated. + * This is useful for determining the target domain for authentication redirects, especially in cloud deployments. + * It is set only in cloud mode to ensure that the cookie is shared across subdomains. + */ export function addAuthOriginDomainCookie(res: FastifyReply) { try { const appCfg = getConfig(); diff --git a/backend/src/server/routes/index.ts b/backend/src/server/routes/index.ts index 4b28105ab..ea4cf9676 100644 --- a/backend/src/server/routes/index.ts +++ b/backend/src/server/routes/index.ts @@ -1555,7 +1555,12 @@ export const registerRoutes = async ( folderService, permissionService, folderDAL, - projectEnvDAL + projectEnvDAL, + secretApprovalRequestService, + secretApprovalPolicyService, + projectDAL, + secretV2BridgeService, + folderCommitDAL }); const identityOidcAuthService = identityOidcAuthServiceFactory({ @@ -1729,7 +1734,9 @@ export const registerRoutes = async ( appConnectionDAL, permissionService, kmsService, - licenseService + licenseService, + gatewayService, + gatewayDAL }); const secretSyncService = secretSyncServiceFactory({ @@ -1827,7 +1834,8 @@ export const registerRoutes = async ( snapshotService, secretQueueService, queueService, - appConnectionDAL + appConnectionDAL, + gatewayService }); const certificateAuthorityService = certificateAuthorityServiceFactory({ diff --git a/backend/src/server/routes/v1/app-connection-routers/app-connection-endpoints.ts b/backend/src/server/routes/v1/app-connection-routers/app-connection-endpoints.ts index 0bc8f7c59..50111b109 100644 --- a/backend/src/server/routes/v1/app-connection-routers/app-connection-endpoints.ts +++ b/backend/src/server/routes/v1/app-connection-routers/app-connection-endpoints.ts @@ -25,12 +25,14 @@ export const registerAppConnectionEndpoints = ; updateSchema: z.ZodType<{ name?: string; credentials?: I["credentials"]; description?: string | null; isPlatformManagedCredentials?: boolean; + gatewayId?: string | null; }>; sanitizedResponseSchema: z.ZodTypeAny; }) => { @@ -224,10 +226,10 @@ export const registerAppConnectionEndpoints = { - const { name, method, credentials, description, isPlatformManagedCredentials } = req.body; + const { name, method, credentials, description, isPlatformManagedCredentials, gatewayId } = req.body; const appConnection = (await server.services.appConnection.createAppConnection( - { name, method, app, credentials, description, isPlatformManagedCredentials }, + { name, method, app, credentials, description, isPlatformManagedCredentials, gatewayId }, req.permission )) as T; @@ -270,11 +272,11 @@ export const registerAppConnectionEndpoints = { - const { name, credentials, description, isPlatformManagedCredentials } = req.body; + const { name, credentials, description, isPlatformManagedCredentials, gatewayId } = req.body; const { connectionId } = req.params; const appConnection = (await server.services.appConnection.updateAppConnection( - { name, credentials, connectionId, description, isPlatformManagedCredentials }, + { name, credentials, connectionId, description, isPlatformManagedCredentials, gatewayId }, req.permission )) as T; diff --git a/backend/src/server/routes/v1/app-connection-routers/app-connection-router.ts b/backend/src/server/routes/v1/app-connection-routers/app-connection-router.ts index 7c1b52edd..ba0826f87 100644 --- a/backend/src/server/routes/v1/app-connection-routers/app-connection-router.ts +++ b/backend/src/server/routes/v1/app-connection-routers/app-connection-router.ts @@ -71,6 +71,7 @@ import { import { LdapConnectionListItemSchema, SanitizedLdapConnectionSchema } from "@app/services/app-connection/ldap"; import { MsSqlConnectionListItemSchema, SanitizedMsSqlConnectionSchema } from "@app/services/app-connection/mssql"; import { MySqlConnectionListItemSchema, SanitizedMySqlConnectionSchema } from "@app/services/app-connection/mysql"; +import { OktaConnectionListItemSchema, SanitizedOktaConnectionSchema } from "@app/services/app-connection/okta"; import { PostgresConnectionListItemSchema, SanitizedPostgresConnectionSchema @@ -138,7 +139,8 @@ const SanitizedAppConnectionSchema = z.union([ ...SanitizedZabbixConnectionSchema.options, ...SanitizedRailwayConnectionSchema.options, ...SanitizedChecklyConnectionSchema.options, - ...SanitizedSupabaseConnectionSchema.options + ...SanitizedSupabaseConnectionSchema.options, + ...SanitizedOktaConnectionSchema.options ]); const AppConnectionOptionsSchema = z.discriminatedUnion("app", [ @@ -175,7 +177,8 @@ const AppConnectionOptionsSchema = z.discriminatedUnion("app", [ ZabbixConnectionListItemSchema, RailwayConnectionListItemSchema, ChecklyConnectionListItemSchema, - SupabaseConnectionListItemSchema + SupabaseConnectionListItemSchema, + OktaConnectionListItemSchema ]); export const registerAppConnectionRouter = async (server: FastifyZodProvider) => { diff --git a/backend/src/server/routes/v1/app-connection-routers/bitbucket-connection-router.ts b/backend/src/server/routes/v1/app-connection-routers/bitbucket-connection-router.ts index 7fe5113e5..23381e65b 100644 --- a/backend/src/server/routes/v1/app-connection-routers/bitbucket-connection-router.ts +++ b/backend/src/server/routes/v1/app-connection-routers/bitbucket-connection-router.ts @@ -85,4 +85,40 @@ export const registerBitbucketConnectionRouter = async (server: FastifyZodProvid return { repositories }; } }); + + server.route({ + method: "GET", + url: `/:connectionId/environments`, + config: { + rateLimit: readLimit + }, + schema: { + params: z.object({ + connectionId: z.string().uuid() + }), + querystring: z.object({ + workspaceSlug: z.string().min(1).max(255), + repositorySlug: z.string().min(1).max(255) + }), + response: { + 200: z.object({ + environments: z.object({ slug: z.string(), name: z.string(), uuid: z.string() }).array() + }) + } + }, + onRequest: verifyAuth([AuthMode.JWT]), + handler: async (req) => { + const { + params: { connectionId }, + query: { workspaceSlug, repositorySlug } + } = req; + + const environments = await server.services.appConnection.bitbucket.listEnvironments( + { connectionId, workspaceSlug, repositorySlug }, + req.permission + ); + + return { environments }; + } + }); }; diff --git a/backend/src/server/routes/v1/app-connection-routers/index.ts b/backend/src/server/routes/v1/app-connection-routers/index.ts index 287a406f6..3bbdc363d 100644 --- a/backend/src/server/routes/v1/app-connection-routers/index.ts +++ b/backend/src/server/routes/v1/app-connection-routers/index.ts @@ -25,6 +25,7 @@ import { registerHumanitecConnectionRouter } from "./humanitec-connection-router import { registerLdapConnectionRouter } from "./ldap-connection-router"; import { registerMsSqlConnectionRouter } from "./mssql-connection-router"; import { registerMySqlConnectionRouter } from "./mysql-connection-router"; +import { registerOktaConnectionRouter } from "./okta-connection-router"; import { registerPostgresConnectionRouter } from "./postgres-connection-router"; import { registerRailwayConnectionRouter } from "./railway-connection-router"; import { registerRenderConnectionRouter } from "./render-connection-router"; @@ -72,5 +73,6 @@ export const APP_CONNECTION_REGISTER_ROUTER_MAP: Record { + registerAppConnectionEndpoints({ + app: AppConnection.Okta, + server, + sanitizedResponseSchema: SanitizedOktaConnectionSchema, + createSchema: CreateOktaConnectionSchema, + updateSchema: UpdateOktaConnectionSchema + }); + + // The below endpoints are not exposed and for Infisical App use + + server.route({ + method: "GET", + url: `/:connectionId/apps`, + config: { + rateLimit: readLimit + }, + schema: { + params: z.object({ + connectionId: z.string().uuid() + }), + response: { + 200: z.object({ + apps: z.object({ id: z.string(), label: z.string() }).array() + }) + } + }, + onRequest: verifyAuth([AuthMode.JWT]), + handler: async (req) => { + const { + params: { connectionId } + } = req; + + const apps = await server.services.appConnection.okta.listApps(connectionId, req.permission); + return { apps }; + } + }); +}; diff --git a/backend/src/server/routes/v1/auth-router.ts b/backend/src/server/routes/v1/auth-router.ts index e7c06ff51..a91548285 100644 --- a/backend/src/server/routes/v1/auth-router.ts +++ b/backend/src/server/routes/v1/auth-router.ts @@ -42,6 +42,14 @@ export const registerAuthRoutes = async (server: FastifyZodProvider) => { maxAge: 0 }); + void res.cookie("aod", "", { + httpOnly: false, + path: "/", + sameSite: "lax", + secure: appCfg.HTTPS_ENABLED, + maxAge: 0 + }); + return { message: "Successfully logged out" }; } }); diff --git a/backend/src/server/routes/v1/project-router.ts b/backend/src/server/routes/v1/project-router.ts index 2015842a5..05aade960 100644 --- a/backend/src/server/routes/v1/project-router.ts +++ b/backend/src/server/routes/v1/project-router.ts @@ -158,7 +158,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => { includeRoles: z .enum(["true", "false"]) .default("false") - .transform((value) => value === "true") + .transform((value) => value === "true"), + type: z.nativeEnum(ProjectType).optional() }), response: { 200: z.object({ @@ -177,7 +178,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => { actorId: req.permission.id, actorAuthMethod: req.permission.authMethod, actor: req.permission.type, - actorOrgId: req.permission.orgId + actorOrgId: req.permission.orgId, + type: req.query.type }); return { workspaces }; } @@ -1050,6 +1052,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => { body: z.object({ limit: z.number().default(100), offset: z.number().default(0), + type: z.nativeEnum(ProjectType).optional(), orderBy: z.nativeEnum(SearchProjectSortBy).optional().default(SearchProjectSortBy.NAME), orderDirection: z.nativeEnum(SortDirection).optional().default(SortDirection.ASC), name: z diff --git a/backend/src/server/routes/v1/secret-sync-routers/bitbucket-sync-router.ts b/backend/src/server/routes/v1/secret-sync-routers/bitbucket-sync-router.ts new file mode 100644 index 000000000..17cd0dbbf --- /dev/null +++ b/backend/src/server/routes/v1/secret-sync-routers/bitbucket-sync-router.ts @@ -0,0 +1,17 @@ +import { + BitbucketSyncSchema, + CreateBitbucketSyncSchema, + UpdateBitbucketSyncSchema +} from "@app/services/secret-sync/bitbucket"; +import { SecretSync } from "@app/services/secret-sync/secret-sync-enums"; + +import { registerSyncSecretsEndpoints } from "./secret-sync-endpoints"; + +export const registerBitbucketSyncRouter = async (server: FastifyZodProvider) => + registerSyncSecretsEndpoints({ + destination: SecretSync.Bitbucket, + server, + responseSchema: BitbucketSyncSchema, + createSchema: CreateBitbucketSyncSchema, + updateSchema: UpdateBitbucketSyncSchema + }); diff --git a/backend/src/server/routes/v1/secret-sync-routers/index.ts b/backend/src/server/routes/v1/secret-sync-routers/index.ts index 8e8f696b7..1b640acae 100644 --- a/backend/src/server/routes/v1/secret-sync-routers/index.ts +++ b/backend/src/server/routes/v1/secret-sync-routers/index.ts @@ -7,6 +7,7 @@ import { registerAwsSecretsManagerSyncRouter } from "./aws-secrets-manager-sync- import { registerAzureAppConfigurationSyncRouter } from "./azure-app-configuration-sync-router"; import { registerAzureDevOpsSyncRouter } from "./azure-devops-sync-router"; import { registerAzureKeyVaultSyncRouter } from "./azure-key-vault-sync-router"; +import { registerBitbucketSyncRouter } from "./bitbucket-sync-router"; import { registerCamundaSyncRouter } from "./camunda-sync-router"; import { registerChecklySyncRouter } from "./checkly-sync-router"; import { registerCloudflarePagesSyncRouter } from "./cloudflare-pages-sync-router"; @@ -57,5 +58,6 @@ export const SECRET_SYNC_REGISTER_ROUTER_MAP: Record { diff --git a/backend/src/services/app-connection/app-connection-enums.ts b/backend/src/services/app-connection/app-connection-enums.ts index 233ce0ea8..7fcdc7217 100644 --- a/backend/src/services/app-connection/app-connection-enums.ts +++ b/backend/src/services/app-connection/app-connection-enums.ts @@ -32,7 +32,8 @@ export enum AppConnection { Railway = "railway", Bitbucket = "bitbucket", Checkly = "checkly", - Supabase = "supabase" + Supabase = "supabase", + Okta = "okta" } export enum AWSRegion { diff --git a/backend/src/services/app-connection/app-connection-fns.ts b/backend/src/services/app-connection/app-connection-fns.ts index 10bab521e..9568761f7 100644 --- a/backend/src/services/app-connection/app-connection-fns.ts +++ b/backend/src/services/app-connection/app-connection-fns.ts @@ -5,6 +5,7 @@ import { validateOCIConnectionCredentials } from "@app/ee/services/app-connections/oci"; import { getOracleDBConnectionListItem, OracleDBConnectionMethod } from "@app/ee/services/app-connections/oracledb"; +import { TGatewayServiceFactory } from "@app/ee/services/gateway/gateway-service"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { crypto } from "@app/lib/crypto/cryptography"; import { BadRequestError } from "@app/lib/errors"; @@ -91,6 +92,7 @@ import { getLdapConnectionListItem, LdapConnectionMethod, validateLdapConnection import { getMsSqlConnectionListItem, MsSqlConnectionMethod } from "./mssql"; import { MySqlConnectionMethod } from "./mysql/mysql-connection-enums"; import { getMySqlConnectionListItem } from "./mysql/mysql-connection-fns"; +import { getOktaConnectionListItem, OktaConnectionMethod, validateOktaConnectionCredentials } from "./okta"; import { getPostgresConnectionListItem, PostgresConnectionMethod } from "./postgres"; import { getRailwayConnectionListItem, validateRailwayConnectionCredentials } from "./railway"; import { RenderConnectionMethod } from "./render/render-connection-enums"; @@ -154,7 +156,8 @@ export const listAppConnectionOptions = () => { getRailwayConnectionListItem(), getBitbucketConnectionListItem(), getChecklyConnectionListItem(), - getSupabaseConnectionListItem() + getSupabaseConnectionListItem(), + getOktaConnectionListItem() ].sort((a, b) => a.name.localeCompare(b.name)); }; @@ -201,7 +204,8 @@ export const decryptAppConnectionCredentials = async ({ }; export const validateAppConnectionCredentials = async ( - appConnection: TAppConnectionConfig + appConnection: TAppConnectionConfig, + gatewayService: Pick ): Promise => { const VALIDATE_APP_CONNECTION_CREDENTIALS_MAP: Record = { [AppConnection.AWS]: validateAwsConnectionCredentials as TAppConnectionCredentialsValidator, @@ -239,10 +243,11 @@ export const validateAppConnectionCredentials = async ( [AppConnection.Railway]: validateRailwayConnectionCredentials as TAppConnectionCredentialsValidator, [AppConnection.Bitbucket]: validateBitbucketConnectionCredentials as TAppConnectionCredentialsValidator, [AppConnection.Checkly]: validateChecklyConnectionCredentials as TAppConnectionCredentialsValidator, - [AppConnection.Supabase]: validateSupabaseConnectionCredentials as TAppConnectionCredentialsValidator + [AppConnection.Supabase]: validateSupabaseConnectionCredentials as TAppConnectionCredentialsValidator, + [AppConnection.Okta]: validateOktaConnectionCredentials as TAppConnectionCredentialsValidator }; - return VALIDATE_APP_CONNECTION_CREDENTIALS_MAP[appConnection.app](appConnection); + return VALIDATE_APP_CONNECTION_CREDENTIALS_MAP[appConnection.app](appConnection, gatewayService); }; export const getAppConnectionMethodName = (method: TAppConnection["method"]) => { @@ -278,6 +283,7 @@ export const getAppConnectionMethodName = (method: TAppConnection["method"]) => case CloudflareConnectionMethod.APIToken: case BitbucketConnectionMethod.ApiToken: case ZabbixConnectionMethod.ApiToken: + case OktaConnectionMethod.ApiToken: return "API Token"; case PostgresConnectionMethod.UsernameAndPassword: case MsSqlConnectionMethod.UsernameAndPassword: @@ -365,7 +371,8 @@ export const TRANSITION_CONNECTION_CREDENTIALS_TO_PLATFORM: Record< [AppConnection.Railway]: platformManagedCredentialsNotSupported, [AppConnection.Bitbucket]: platformManagedCredentialsNotSupported, [AppConnection.Checkly]: platformManagedCredentialsNotSupported, - [AppConnection.Supabase]: platformManagedCredentialsNotSupported + [AppConnection.Supabase]: platformManagedCredentialsNotSupported, + [AppConnection.Okta]: platformManagedCredentialsNotSupported }; export const enterpriseAppCheck = async ( diff --git a/backend/src/services/app-connection/app-connection-maps.ts b/backend/src/services/app-connection/app-connection-maps.ts index 8a85020d8..03b979312 100644 --- a/backend/src/services/app-connection/app-connection-maps.ts +++ b/backend/src/services/app-connection/app-connection-maps.ts @@ -34,7 +34,8 @@ export const APP_CONNECTION_NAME_MAP: Record = { [AppConnection.Railway]: "Railway", [AppConnection.Bitbucket]: "Bitbucket", [AppConnection.Checkly]: "Checkly", - [AppConnection.Supabase]: "Supabase" + [AppConnection.Supabase]: "Supabase", + [AppConnection.Okta]: "Okta" }; export const APP_CONNECTION_PLAN_MAP: Record = { @@ -71,5 +72,6 @@ export const APP_CONNECTION_PLAN_MAP: Record z.object({ name: slugSchema({ field: "name" }).describe(AppConnections.CREATE(app).name), @@ -30,12 +30,23 @@ export const GenericCreateAppConnectionFieldsSchema = ( .describe(AppConnections.CREATE(app).description), isPlatformManagedCredentials: supportsPlatformManagedCredentials ? z.boolean().optional().default(false).describe(AppConnections.CREATE(app).isPlatformManagedCredentials) - : z.literal(false).optional().describe(`Not supported for ${APP_CONNECTION_NAME_MAP[app]} Connections.`) + : z + .literal(false, { + errorMap: () => ({ message: `Not supported for ${APP_CONNECTION_NAME_MAP[app]} Connections` }) + }) + .optional() + .describe(`Not supported for ${APP_CONNECTION_NAME_MAP[app]} Connections.`), + gatewayId: supportsGateways + ? z.string().uuid().nullish().describe("The Gateway ID to use for this connection.") + : z + .undefined({ message: `Not supported for ${APP_CONNECTION_NAME_MAP[app]} Connections` }) + .or(z.null({ message: `Not supported for ${APP_CONNECTION_NAME_MAP[app]} Connections` })) + .describe(`Not supported for ${APP_CONNECTION_NAME_MAP[app]} Connections.`) }); export const GenericUpdateAppConnectionFieldsSchema = ( app: AppConnection, - { supportsPlatformManagedCredentials = false }: TAppConnectionBaseConfig = {} + { supportsPlatformManagedCredentials = false, supportsGateways = false }: TAppConnectionBaseConfig = {} ) => z.object({ name: slugSchema({ field: "name" }).describe(AppConnections.UPDATE(app).name).optional(), @@ -47,5 +58,16 @@ export const GenericUpdateAppConnectionFieldsSchema = ( .describe(AppConnections.UPDATE(app).description), isPlatformManagedCredentials: supportsPlatformManagedCredentials ? z.boolean().optional().describe(AppConnections.UPDATE(app).isPlatformManagedCredentials) - : z.literal(false).optional().describe(`Not supported for ${APP_CONNECTION_NAME_MAP[app]} Connections.`) + : z + .literal(false, { + errorMap: () => ({ message: `Not supported for ${APP_CONNECTION_NAME_MAP[app]} Connections` }) + }) + .optional() + .describe(`Not supported for ${APP_CONNECTION_NAME_MAP[app]} Connections.`), + gatewayId: supportsGateways + ? z.string().uuid().nullish().describe("The Gateway ID to use for this connection.") + : z + .undefined({ message: `Not supported for ${APP_CONNECTION_NAME_MAP[app]} Connections` }) + .or(z.null({ message: `Not supported for ${APP_CONNECTION_NAME_MAP[app]} Connections` })) + .describe(`Not supported for ${APP_CONNECTION_NAME_MAP[app]} Connections.`) }); diff --git a/backend/src/services/app-connection/app-connection-service.ts b/backend/src/services/app-connection/app-connection-service.ts index 1f3e76f8e..86be7ac8d 100644 --- a/backend/src/services/app-connection/app-connection-service.ts +++ b/backend/src/services/app-connection/app-connection-service.ts @@ -3,8 +3,14 @@ import { ForbiddenError, subject } from "@casl/ability"; import { ValidateOCIConnectionCredentialsSchema } from "@app/ee/services/app-connections/oci"; import { ociConnectionService } from "@app/ee/services/app-connections/oci/oci-connection-service"; import { ValidateOracleDBConnectionCredentialsSchema } from "@app/ee/services/app-connections/oracledb"; +import { TGatewayDALFactory } from "@app/ee/services/gateway/gateway-dal"; +import { TGatewayServiceFactory } from "@app/ee/services/gateway/gateway-service"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; -import { OrgPermissionAppConnectionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; +import { + OrgPermissionAppConnectionActions, + OrgPermissionGatewayActions, + OrgPermissionSubjects +} from "@app/ee/services/permission/org-permission"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { crypto } from "@app/lib/crypto/cryptography"; import { DatabaseErrorCode } from "@app/lib/error-codes"; @@ -73,6 +79,8 @@ import { humanitecConnectionService } from "./humanitec/humanitec-connection-ser import { ValidateLdapConnectionCredentialsSchema } from "./ldap"; import { ValidateMsSqlConnectionCredentialsSchema } from "./mssql"; import { ValidateMySqlConnectionCredentialsSchema } from "./mysql"; +import { ValidateOktaConnectionCredentialsSchema } from "./okta"; +import { oktaConnectionService } from "./okta/okta-connection-service"; import { ValidatePostgresConnectionCredentialsSchema } from "./postgres"; import { ValidateRailwayConnectionCredentialsSchema } from "./railway"; import { railwayConnectionService } from "./railway/railway-connection-service"; @@ -96,6 +104,8 @@ export type TAppConnectionServiceFactoryDep = { permissionService: Pick; kmsService: Pick; licenseService: Pick; + gatewayService: Pick; + gatewayDAL: Pick; }; export type TAppConnectionServiceFactory = ReturnType; @@ -134,14 +144,17 @@ const VALIDATE_APP_CONNECTION_CREDENTIALS_MAP: Record { const listAppConnectionsByOrg = async (actor: OrgServiceActor, app?: AppConnection) => { const { permission } = await permissionService.getOrgPermission( @@ -222,7 +235,7 @@ export const appConnectionServiceFactory = ({ }; const createAppConnection = async ( - { method, app, credentials, ...params }: TCreateAppConnectionDTO, + { method, app, credentials, gatewayId, ...params }: TCreateAppConnectionDTO, actor: OrgServiceActor ) => { const { permission } = await permissionService.getOrgPermission( @@ -238,6 +251,20 @@ export const appConnectionServiceFactory = ({ OrgPermissionSubjects.AppConnections ); + if (gatewayId) { + ForbiddenError.from(permission).throwUnlessCan( + OrgPermissionGatewayActions.AttachGateways, + OrgPermissionSubjects.Gateway + ); + + const [gateway] = await gatewayDAL.find({ id: gatewayId, orgId: actor.orgId }); + if (!gateway) { + throw new NotFoundError({ + message: `Gateway with ID ${gatewayId} not found for org` + }); + } + } + await enterpriseAppCheck( licenseService, app, @@ -245,12 +272,16 @@ export const appConnectionServiceFactory = ({ "Failed to create app connection due to plan restriction. Upgrade plan to access enterprise app connections." ); - const validatedCredentials = await validateAppConnectionCredentials({ - app, - credentials, - method, - orgId: actor.orgId - } as TAppConnectionConfig); + const validatedCredentials = await validateAppConnectionCredentials( + { + app, + credentials, + method, + orgId: actor.orgId, + gatewayId + } as TAppConnectionConfig, + gatewayService + ); try { const createConnection = async (connectionCredentials: TAppConnection["credentials"]) => { @@ -265,6 +296,7 @@ export const appConnectionServiceFactory = ({ encryptedCredentials, method, app, + gatewayId, ...params }); }; @@ -277,9 +309,11 @@ export const appConnectionServiceFactory = ({ app, orgId: actor.orgId, credentials: validatedCredentials, - method + method, + gatewayId } as TAppConnectionConfig, - (platformCredentials) => createConnection(platformCredentials) + (platformCredentials) => createConnection(platformCredentials), + gatewayService ); } else { connection = await createConnection(validatedCredentials); @@ -300,7 +334,7 @@ export const appConnectionServiceFactory = ({ }; const updateAppConnection = async ( - { connectionId, credentials, ...params }: TUpdateAppConnectionDTO, + { connectionId, credentials, gatewayId, ...params }: TUpdateAppConnectionDTO, actor: OrgServiceActor ) => { const appConnection = await appConnectionDAL.findById(connectionId); @@ -327,6 +361,22 @@ export const appConnectionServiceFactory = ({ OrgPermissionSubjects.AppConnections ); + if (gatewayId !== appConnection.gatewayId) { + ForbiddenError.from(permission).throwUnlessCan( + OrgPermissionGatewayActions.AttachGateways, + OrgPermissionSubjects.Gateway + ); + + if (gatewayId) { + const [gateway] = await gatewayDAL.find({ id: gatewayId, orgId: actor.orgId }); + if (!gateway) { + throw new NotFoundError({ + message: `Gateway with ID ${gatewayId} not found for org` + }); + } + } + } + // prevent updating credentials or management status if platform managed if (appConnection.isPlatformManagedCredentials && (params.isPlatformManagedCredentials === false || credentials)) { throw new BadRequestError({ @@ -351,12 +401,16 @@ export const appConnectionServiceFactory = ({ } Connection with method ${getAppConnectionMethodName(method)}` }); - updatedCredentials = await validateAppConnectionCredentials({ - app, - orgId: actor.orgId, - credentials, - method - } as TAppConnectionConfig); + updatedCredentials = await validateAppConnectionCredentials( + { + app, + orgId: actor.orgId, + credentials, + method, + gatewayId + } as TAppConnectionConfig, + gatewayService + ); if (!updatedCredentials) throw new BadRequestError({ message: "Unable to validate connection - check credentials" }); @@ -375,6 +429,7 @@ export const appConnectionServiceFactory = ({ return appConnectionDAL.updateById(connectionId, { orgId: actor.orgId, encryptedCredentials, + gatewayId, ...params }); }; @@ -391,9 +446,11 @@ export const appConnectionServiceFactory = ({ app, orgId: actor.orgId, credentials: updatedCredentials, - method + method, + gatewayId } as TAppConnectionConfig, - (platformCredentials) => updateConnection(platformCredentials) + (platformCredentials) => updateConnection(platformCredentials), + gatewayService ); } else { updatedConnection = await updateConnection(updatedCredentials); @@ -549,6 +606,7 @@ export const appConnectionServiceFactory = ({ railway: railwayConnectionService(connectAppConnectionById), bitbucket: bitbucketConnectionService(connectAppConnectionById), checkly: checklyConnectionService(connectAppConnectionById), - supabase: supabaseConnectionService(connectAppConnectionById) + supabase: supabaseConnectionService(connectAppConnectionById), + okta: oktaConnectionService(connectAppConnectionById) }; }; diff --git a/backend/src/services/app-connection/app-connection-types.ts b/backend/src/services/app-connection/app-connection-types.ts index bb6be0a70..6a0c27b7f 100644 --- a/backend/src/services/app-connection/app-connection-types.ts +++ b/backend/src/services/app-connection/app-connection-types.ts @@ -9,6 +9,7 @@ import { TOracleDBConnectionInput, TValidateOracleDBConnectionCredentialsSchema } from "@app/ee/services/app-connections/oracledb"; +import { TGatewayServiceFactory } from "@app/ee/services/gateway/gateway-service"; import { TAppConnectionDALFactory } from "@app/services/app-connection/app-connection-dal"; import { TSqlConnectionConfig } from "@app/services/app-connection/shared/sql/sql-connection-types"; import { SecretSync } from "@app/services/secret-sync/secret-sync-enums"; @@ -142,6 +143,12 @@ import { } from "./ldap"; import { TMsSqlConnection, TMsSqlConnectionInput, TValidateMsSqlConnectionCredentialsSchema } from "./mssql"; import { TMySqlConnection, TMySqlConnectionInput, TValidateMySqlConnectionCredentialsSchema } from "./mysql"; +import { + TOktaConnection, + TOktaConnectionConfig, + TOktaConnectionInput, + TValidateOktaConnectionCredentialsSchema +} from "./okta"; import { TPostgresConnection, TPostgresConnectionInput, @@ -231,6 +238,7 @@ export type TAppConnection = { id: string } & ( | TRailwayConnection | TChecklyConnection | TSupabaseConnection + | TOktaConnection ); export type TAppConnectionRaw = NonNullable>>; @@ -272,6 +280,7 @@ export type TAppConnectionInput = { id: string } & ( | TRailwayConnectionInput | TChecklyConnectionInput | TSupabaseConnectionInput + | TOktaConnectionInput ); export type TSqlConnectionInput = @@ -282,7 +291,7 @@ export type TSqlConnectionInput = export type TCreateAppConnectionDTO = Pick< TAppConnectionInput, - "credentials" | "method" | "name" | "app" | "description" | "isPlatformManagedCredentials" + "credentials" | "method" | "name" | "app" | "description" | "isPlatformManagedCredentials" | "gatewayId" >; export type TUpdateAppConnectionDTO = Partial> & { @@ -320,7 +329,8 @@ export type TAppConnectionConfig = | TZabbixConnectionConfig | TRailwayConnectionConfig | TChecklyConnectionConfig - | TSupabaseConnectionConfig; + | TSupabaseConnectionConfig + | TOktaConnectionConfig; export type TValidateAppConnectionCredentialsSchema = | TValidateAwsConnectionCredentialsSchema @@ -356,7 +366,8 @@ export type TValidateAppConnectionCredentialsSchema = | TValidateZabbixConnectionCredentialsSchema | TValidateRailwayConnectionCredentialsSchema | TValidateChecklyConnectionCredentialsSchema - | TValidateSupabaseConnectionCredentialsSchema; + | TValidateSupabaseConnectionCredentialsSchema + | TValidateOktaConnectionCredentialsSchema; export type TListAwsConnectionKmsKeys = { connectionId: string; @@ -369,14 +380,17 @@ export type TListAwsConnectionIamUsers = { }; export type TAppConnectionCredentialsValidator = ( - appConnection: TAppConnectionConfig + appConnection: TAppConnectionConfig, + gatewayService: Pick ) => Promise; export type TAppConnectionTransitionCredentialsToPlatform = ( appConnection: TAppConnectionConfig, - callback: (credentials: TAppConnection["credentials"]) => Promise + callback: (credentials: TAppConnection["credentials"]) => Promise, + gatewayService: Pick ) => Promise; export type TAppConnectionBaseConfig = { supportsPlatformManagedCredentials?: boolean; + supportsGateways?: boolean; }; diff --git a/backend/src/services/app-connection/bitbucket/bitbucket-connection-fns.ts b/backend/src/services/app-connection/bitbucket/bitbucket-connection-fns.ts index 2d418a8a3..4abf879f8 100644 --- a/backend/src/services/app-connection/bitbucket/bitbucket-connection-fns.ts +++ b/backend/src/services/app-connection/bitbucket/bitbucket-connection-fns.ts @@ -9,6 +9,7 @@ import { BitbucketConnectionMethod } from "./bitbucket-connection-enums"; import { TBitbucketConnection, TBitbucketConnectionConfig, + TBitbucketEnvironment, TBitbucketRepo, TBitbucketWorkspace } from "./bitbucket-connection-types"; @@ -21,11 +22,15 @@ export const getBitbucketConnectionListItem = () => { }; }; +export const createAuthHeader = (email: string, apiToken: string): string => { + return `Basic ${Buffer.from(`${email}:${apiToken}`).toString("base64")}`; +}; + export const getBitbucketUser = async ({ email, apiToken }: { email: string; apiToken: string }) => { try { const { data } = await request.get<{ username: string }>(`${IntegrationUrls.BITBUCKET_API_URL}/2.0/user`, { headers: { - Authorization: `Basic ${Buffer.from(`${email}:${apiToken}`).toString("base64")}`, + Authorization: createAuthHeader(email, apiToken), Accept: "application/json" } }); @@ -57,7 +62,7 @@ export const listBitbucketWorkspaces = async (appConnection: TBitbucketConnectio const { email, apiToken } = appConnection.credentials; const headers = { - Authorization: `Basic ${Buffer.from(`${email}:${apiToken}`).toString("base64")}`, + Authorization: createAuthHeader(email, apiToken), Accept: "application/json" }; @@ -89,7 +94,7 @@ export const listBitbucketRepositories = async (appConnection: TBitbucketConnect const { email, apiToken } = appConnection.credentials; const headers = { - Authorization: `Basic ${Buffer.from(`${email}:${apiToken}`).toString("base64")}`, + Authorization: createAuthHeader(email, apiToken), Accept: "application/json" }; @@ -115,3 +120,43 @@ export const listBitbucketRepositories = async (appConnection: TBitbucketConnect return allRepos; }; + +export const listBitbucketEnvironments = async ( + appConnection: TBitbucketConnection, + workspaceSlug: string, + repositorySlug: string +) => { + const { email, apiToken } = appConnection.credentials; + + const headers = { + Authorization: createAuthHeader(email, apiToken), + Accept: "application/json" + }; + + const environments: TBitbucketEnvironment[] = []; + let hasNextPage = true; + + let environmentsUrl = `${IntegrationUrls.BITBUCKET_API_URL}/2.0/repositories/${encodeURIComponent(workspaceSlug)}/${encodeURIComponent(repositorySlug)}/environments?pagelen=100`; + + let iterationCount = 0; + // Limit to 10 iterations, fetching at most 10 * 100 = 1000 environments + while (hasNextPage && iterationCount < 10) { + // eslint-disable-next-line no-await-in-loop + const { data }: { data: { values: TBitbucketEnvironment[]; next: string } } = await request.get(environmentsUrl, { + headers + }); + + if (data?.values.length > 0) { + environments.push(...data.values); + } + + if (data.next) { + environmentsUrl = data.next; + } else { + hasNextPage = false; + } + iterationCount += 1; + } + + return environments; +}; diff --git a/backend/src/services/app-connection/bitbucket/bitbucket-connection-service.ts b/backend/src/services/app-connection/bitbucket/bitbucket-connection-service.ts index f08a8d276..b995cb9c0 100644 --- a/backend/src/services/app-connection/bitbucket/bitbucket-connection-service.ts +++ b/backend/src/services/app-connection/bitbucket/bitbucket-connection-service.ts @@ -1,8 +1,16 @@ import { OrgServiceActor } from "@app/lib/types"; import { AppConnection } from "../app-connection-enums"; -import { listBitbucketRepositories, listBitbucketWorkspaces } from "./bitbucket-connection-fns"; -import { TBitbucketConnection, TGetBitbucketRepositoriesDTO } from "./bitbucket-connection-types"; +import { + listBitbucketEnvironments, + listBitbucketRepositories, + listBitbucketWorkspaces +} from "./bitbucket-connection-fns"; +import { + TBitbucketConnection, + TGetBitbucketEnvironmentsDTO, + TGetBitbucketRepositoriesDTO +} from "./bitbucket-connection-types"; type TGetAppConnectionFunc = ( app: AppConnection, @@ -26,8 +34,18 @@ export const bitbucketConnectionService = (getAppConnection: TGetAppConnectionFu return repositories; }; + const listEnvironments = async ( + { connectionId, workspaceSlug, repositorySlug }: TGetBitbucketEnvironmentsDTO, + actor: OrgServiceActor + ) => { + const appConnection = await getAppConnection(AppConnection.Bitbucket, connectionId, actor); + const environments = await listBitbucketEnvironments(appConnection, workspaceSlug, repositorySlug); + return environments; + }; + return { listWorkspaces, - listRepositories + listRepositories, + listEnvironments }; }; diff --git a/backend/src/services/app-connection/bitbucket/bitbucket-connection-types.ts b/backend/src/services/app-connection/bitbucket/bitbucket-connection-types.ts index b0694c6e3..40af42321 100644 --- a/backend/src/services/app-connection/bitbucket/bitbucket-connection-types.ts +++ b/backend/src/services/app-connection/bitbucket/bitbucket-connection-types.ts @@ -38,3 +38,20 @@ export type TBitbucketRepo = { full_name: string; // workspace-slug/repo-slug slug: string; }; + +export type TGetBitbucketEnvironmentsDTO = { + connectionId: string; + workspaceSlug: string; + repositorySlug: string; +}; + +export type TBitbucketEnvironment = { + uuid: string; + slug: string; + name: string; +}; + +export type TBitbucketEnvironmentsResponse = { + values: TBitbucketEnvironment[]; + next?: string; +}; diff --git a/backend/src/services/app-connection/github-radar/github-radar-connection-fns.ts b/backend/src/services/app-connection/github-radar/github-radar-connection-fns.ts index 84d7a1ce1..fba852a0a 100644 --- a/backend/src/services/app-connection/github-radar/github-radar-connection-fns.ts +++ b/backend/src/services/app-connection/github-radar/github-radar-connection-fns.ts @@ -9,6 +9,7 @@ import { getAppConnectionMethodName } from "@app/services/app-connection/app-con import { IntegrationUrls } from "@app/services/integration-auth/integration-list"; import { AppConnection } from "../app-connection-enums"; +import { GithubTokenRespData, isGithubErrorResponse } from "../github/github-connection-fns"; import { GitHubRadarConnectionMethod } from "./github-radar-connection-enums"; import { TGitHubRadarConnection, @@ -71,13 +72,6 @@ export const listGitHubRadarRepositories = async (appConnection: TGitHubRadarCon return repositories; }; -type TokenRespData = { - access_token: string; - scope: string; - token_type: string; - error?: string; -}; - export const validateGitHubRadarConnectionCredentials = async (config: TGitHubRadarConnectionConfig) => { const { credentials, method } = config; @@ -93,10 +87,10 @@ export const validateGitHubRadarConnectionCredentials = async (config: TGitHubRa }); } - let tokenResp: AxiosResponse; + let tokenResp: AxiosResponse; try { - tokenResp = await request.get("https://github.com/login/oauth/access_token", { + tokenResp = await request.get("https://github.com/login/oauth/access_token", { params: { client_id: INF_APP_CONNECTION_GITHUB_RADAR_APP_CLIENT_ID, client_secret: INF_APP_CONNECTION_GITHUB_RADAR_APP_CLIENT_SECRET, @@ -108,19 +102,27 @@ export const validateGitHubRadarConnectionCredentials = async (config: TGitHubRa "Accept-Encoding": "application/json" } }); + + if (isGithubErrorResponse(tokenResp?.data)) { + throw new BadRequestError({ + message: `Unable to validate credentials: GitHub responded with an error: ${tokenResp.data.error} - ${tokenResp.data.error_description}` + }); + } } catch (e: unknown) { + if (e instanceof BadRequestError) { + throw e; + } + throw new BadRequestError({ message: `Unable to validate connection: verify credentials` }); } - if (tokenResp.status !== 200) { - throw new BadRequestError({ - message: `Unable to validate credentials: GitHub responded with a status code of ${tokenResp.status} (${tokenResp.statusText}). Verify credentials and try again.` - }); - } - if (method === GitHubRadarConnectionMethod.App) { + if (!tokenResp.data.access_token) { + throw new InternalServerError({ message: `Missing access token: ${tokenResp.data.error}` }); + } + const installationsResp = await request.get<{ installations: { id: number; @@ -149,10 +151,6 @@ export const validateGitHubRadarConnectionCredentials = async (config: TGitHubRa } } - if (!tokenResp.data.access_token) { - throw new InternalServerError({ message: `Missing access token: ${tokenResp.data.error}` }); - } - switch (method) { case GitHubRadarConnectionMethod.App: return { diff --git a/backend/src/services/app-connection/github/github-connection-fns.ts b/backend/src/services/app-connection/github/github-connection-fns.ts index e4281625b..360923e19 100644 --- a/backend/src/services/app-connection/github/github-connection-fns.ts +++ b/backend/src/services/app-connection/github/github-connection-fns.ts @@ -144,14 +144,14 @@ export const getGitHubEnvironments = async (appConnection: TGitHubConnection, ow } }; -type TokenRespData = { +export type GithubTokenRespData = { access_token?: string; scope: string; token_type: string; error?: string; }; -function isErrorResponse(data: TokenRespData): data is TokenRespData & { +export function isGithubErrorResponse(data: GithubTokenRespData): data is GithubTokenRespData & { error: string; error_description: string; error_uri: string; @@ -191,10 +191,10 @@ export const validateGitHubConnectionCredentials = async (config: TGitHubConnect }); } - let tokenResp: AxiosResponse; + let tokenResp: AxiosResponse; try { - tokenResp = await request.get("https://github.com/login/oauth/access_token", { + tokenResp = await request.get("https://github.com/login/oauth/access_token", { params: { client_id: clientId, client_secret: clientSecret, @@ -207,7 +207,7 @@ export const validateGitHubConnectionCredentials = async (config: TGitHubConnect } }); - if (isErrorResponse(tokenResp?.data)) { + if (isGithubErrorResponse(tokenResp?.data)) { throw new BadRequestError({ message: `Unable to validate credentials: GitHub responded with an error: ${tokenResp.data.error} - ${tokenResp.data.error_description}` }); diff --git a/backend/src/services/app-connection/mssql/mssql-connection-schemas.ts b/backend/src/services/app-connection/mssql/mssql-connection-schemas.ts index 994f9a40d..f8d380949 100644 --- a/backend/src/services/app-connection/mssql/mssql-connection-schemas.ts +++ b/backend/src/services/app-connection/mssql/mssql-connection-schemas.ts @@ -49,7 +49,10 @@ export const ValidateMsSqlConnectionCredentialsSchema = z.discriminatedUnion("me ]); export const CreateMsSqlConnectionSchema = ValidateMsSqlConnectionCredentialsSchema.and( - GenericCreateAppConnectionFieldsSchema(AppConnection.MsSql, { supportsPlatformManagedCredentials: true }) + GenericCreateAppConnectionFieldsSchema(AppConnection.MsSql, { + supportsPlatformManagedCredentials: true, + supportsGateways: true + }) ); export const UpdateMsSqlConnectionSchema = z @@ -58,7 +61,12 @@ export const UpdateMsSqlConnectionSchema = z AppConnections.UPDATE(AppConnection.MsSql).credentials ) }) - .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.MsSql, { supportsPlatformManagedCredentials: true })); + .and( + GenericUpdateAppConnectionFieldsSchema(AppConnection.MsSql, { + supportsPlatformManagedCredentials: true, + supportsGateways: true + }) + ); export const MsSqlConnectionListItemSchema = z.object({ name: z.literal("Microsoft SQL Server"), diff --git a/backend/src/services/app-connection/mysql/mysql-connection-schemas.ts b/backend/src/services/app-connection/mysql/mysql-connection-schemas.ts index 082bac557..51a533395 100644 --- a/backend/src/services/app-connection/mysql/mysql-connection-schemas.ts +++ b/backend/src/services/app-connection/mysql/mysql-connection-schemas.ts @@ -47,7 +47,10 @@ export const ValidateMySqlConnectionCredentialsSchema = z.discriminatedUnion("me ]); export const CreateMySqlConnectionSchema = ValidateMySqlConnectionCredentialsSchema.and( - GenericCreateAppConnectionFieldsSchema(AppConnection.MySql, { supportsPlatformManagedCredentials: true }) + GenericCreateAppConnectionFieldsSchema(AppConnection.MySql, { + supportsPlatformManagedCredentials: true, + supportsGateways: true + }) ); export const UpdateMySqlConnectionSchema = z @@ -56,7 +59,12 @@ export const UpdateMySqlConnectionSchema = z AppConnections.UPDATE(AppConnection.MySql).credentials ) }) - .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.MySql, { supportsPlatformManagedCredentials: true })); + .and( + GenericUpdateAppConnectionFieldsSchema(AppConnection.MySql, { + supportsPlatformManagedCredentials: true, + supportsGateways: true + }) + ); export const MySqlConnectionListItemSchema = z.object({ name: z.literal("MySQL"), diff --git a/backend/src/services/app-connection/okta/index.ts b/backend/src/services/app-connection/okta/index.ts new file mode 100644 index 000000000..ce06fe7e2 --- /dev/null +++ b/backend/src/services/app-connection/okta/index.ts @@ -0,0 +1,4 @@ +export * from "./okta-connection-enums"; +export * from "./okta-connection-fns"; +export * from "./okta-connection-schemas"; +export * from "./okta-connection-types"; diff --git a/backend/src/services/app-connection/okta/okta-connection-enums.ts b/backend/src/services/app-connection/okta/okta-connection-enums.ts new file mode 100644 index 000000000..75bd5ea61 --- /dev/null +++ b/backend/src/services/app-connection/okta/okta-connection-enums.ts @@ -0,0 +1,3 @@ +export enum OktaConnectionMethod { + ApiToken = "api-token" +} diff --git a/backend/src/services/app-connection/okta/okta-connection-fns.ts b/backend/src/services/app-connection/okta/okta-connection-fns.ts new file mode 100644 index 000000000..a48eebbb8 --- /dev/null +++ b/backend/src/services/app-connection/okta/okta-connection-fns.ts @@ -0,0 +1,57 @@ +import { request } from "@app/lib/config/request"; +import { UnauthorizedError } from "@app/lib/errors"; +import { removeTrailingSlash } from "@app/lib/fn"; +import { blockLocalAndPrivateIpAddresses } from "@app/lib/validator"; +import { AppConnection } from "@app/services/app-connection/app-connection-enums"; + +import { OktaConnectionMethod } from "./okta-connection-enums"; +import { TOktaApp, TOktaConnection, TOktaConnectionConfig } from "./okta-connection-types"; + +export const getOktaConnectionListItem = () => { + return { + name: "Okta" as const, + app: AppConnection.Okta as const, + methods: Object.values(OktaConnectionMethod) as [OktaConnectionMethod.ApiToken] + }; +}; + +export const getOktaInstanceUrl = async (config: TOktaConnectionConfig) => { + const instanceUrl = removeTrailingSlash(config.credentials.instanceUrl); + await blockLocalAndPrivateIpAddresses(instanceUrl); + return instanceUrl; +}; + +export const validateOktaConnectionCredentials = async (config: TOktaConnectionConfig) => { + const { apiToken } = config.credentials; + const instanceUrl = await getOktaInstanceUrl(config); + + try { + await request.get(`${instanceUrl}/api/v1/users/me`, { + headers: { + Accept: "application/json", + Authorization: `SSWS ${apiToken}` + }, + validateStatus: (status) => status === 200 + }); + } catch (error: unknown) { + throw new UnauthorizedError({ + message: "Unable to validate connection: invalid credentials" + }); + } + + return config.credentials; +}; + +export const listOktaApps = async (appConnection: TOktaConnection) => { + const { apiToken } = appConnection.credentials; + const instanceUrl = await getOktaInstanceUrl(appConnection); + + const { data } = await request.get(`${instanceUrl}/api/v1/apps`, { + headers: { + Accept: "application/json", + Authorization: `SSWS ${apiToken}` + } + }); + + return data.filter((app) => app.status === "ACTIVE" && app.name === "oidc_client"); +}; diff --git a/backend/src/services/app-connection/okta/okta-connection-schemas.ts b/backend/src/services/app-connection/okta/okta-connection-schemas.ts new file mode 100644 index 000000000..37ce0ec11 --- /dev/null +++ b/backend/src/services/app-connection/okta/okta-connection-schemas.ts @@ -0,0 +1,69 @@ +import RE2 from "re2"; +import z from "zod"; + +import { AppConnections } from "@app/lib/api-docs"; +import { AppConnection } from "@app/services/app-connection/app-connection-enums"; +import { + BaseAppConnectionSchema, + GenericCreateAppConnectionFieldsSchema, + GenericUpdateAppConnectionFieldsSchema +} from "@app/services/app-connection/app-connection-schemas"; + +import { OktaConnectionMethod } from "./okta-connection-enums"; + +export const OktaConnectionApiTokenCredentialsSchema = z.object({ + instanceUrl: z + .string() + .trim() + .url("Invalid Instance URL") + .min(1, "Instance URL required") + .max(255) + .describe(AppConnections.CREDENTIALS.OKTA.instanceUrl), + apiToken: z + .string() + .trim() + .min(1, "API Token required") + .refine((value) => new RE2("^00[a-zA-Z0-9_-]{40}$").test(value), "Invalid Okta API Token format") + .describe(AppConnections.CREDENTIALS.OKTA.apiToken) +}); + +const BaseOktaConnectionSchema = BaseAppConnectionSchema.extend({ app: z.literal(AppConnection.Okta) }); + +export const OktaConnectionSchema = BaseOktaConnectionSchema.extend({ + method: z.literal(OktaConnectionMethod.ApiToken), + credentials: OktaConnectionApiTokenCredentialsSchema +}); + +export const SanitizedOktaConnectionSchema = z.discriminatedUnion("method", [ + BaseOktaConnectionSchema.extend({ + method: z.literal(OktaConnectionMethod.ApiToken), + credentials: OktaConnectionApiTokenCredentialsSchema.pick({ + instanceUrl: true + }) + }) +]); + +export const ValidateOktaConnectionCredentialsSchema = z.discriminatedUnion("method", [ + z.object({ + method: z.literal(OktaConnectionMethod.ApiToken).describe(AppConnections.CREATE(AppConnection.Okta).method), + credentials: OktaConnectionApiTokenCredentialsSchema.describe(AppConnections.CREATE(AppConnection.Okta).credentials) + }) +]); + +export const CreateOktaConnectionSchema = ValidateOktaConnectionCredentialsSchema.and( + GenericCreateAppConnectionFieldsSchema(AppConnection.Okta) +); + +export const UpdateOktaConnectionSchema = z + .object({ + credentials: OktaConnectionApiTokenCredentialsSchema.optional().describe( + AppConnections.UPDATE(AppConnection.Okta).credentials + ) + }) + .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Okta)); + +export const OktaConnectionListItemSchema = z.object({ + name: z.literal("Okta"), + app: z.literal(AppConnection.Okta), + methods: z.nativeEnum(OktaConnectionMethod).array() +}); diff --git a/backend/src/services/app-connection/okta/okta-connection-service.ts b/backend/src/services/app-connection/okta/okta-connection-service.ts new file mode 100644 index 000000000..8ac036dcd --- /dev/null +++ b/backend/src/services/app-connection/okta/okta-connection-service.ts @@ -0,0 +1,23 @@ +import { OrgServiceActor } from "@app/lib/types"; + +import { AppConnection } from "../app-connection-enums"; +import { listOktaApps } from "./okta-connection-fns"; +import { TOktaConnection } from "./okta-connection-types"; + +type TGetAppConnectionFunc = ( + app: AppConnection, + connectionId: string, + actor: OrgServiceActor +) => Promise; + +export const oktaConnectionService = (getAppConnection: TGetAppConnectionFunc) => { + const listApps = async (connectionId: string, actor: OrgServiceActor) => { + const appConnection = await getAppConnection(AppConnection.Okta, connectionId, actor); + const apps = await listOktaApps(appConnection); + return apps; + }; + + return { + listApps + }; +}; diff --git a/backend/src/services/app-connection/okta/okta-connection-types.ts b/backend/src/services/app-connection/okta/okta-connection-types.ts new file mode 100644 index 000000000..8ed53aaed --- /dev/null +++ b/backend/src/services/app-connection/okta/okta-connection-types.ts @@ -0,0 +1,29 @@ +import z from "zod"; + +import { DiscriminativePick } from "@app/lib/types"; + +import { AppConnection } from "../app-connection-enums"; +import { + CreateOktaConnectionSchema, + OktaConnectionSchema, + ValidateOktaConnectionCredentialsSchema +} from "./okta-connection-schemas"; + +export type TOktaConnection = z.infer; + +export type TOktaConnectionInput = z.infer & { + app: AppConnection.Okta; +}; + +export type TValidateOktaConnectionCredentialsSchema = typeof ValidateOktaConnectionCredentialsSchema; + +export type TOktaConnectionConfig = DiscriminativePick & { + orgId: string; +}; + +export type TOktaApp = { + id: string; + label: string; + status: "ACTIVE" | "INACTIVE"; + name: "oidc_client"; // "oidc_client" or other types +}; diff --git a/backend/src/services/app-connection/postgres/postgres-connection-schemas.ts b/backend/src/services/app-connection/postgres/postgres-connection-schemas.ts index 1ddf1e2da..da74bd669 100644 --- a/backend/src/services/app-connection/postgres/postgres-connection-schemas.ts +++ b/backend/src/services/app-connection/postgres/postgres-connection-schemas.ts @@ -47,7 +47,10 @@ export const ValidatePostgresConnectionCredentialsSchema = z.discriminatedUnion( ]); export const CreatePostgresConnectionSchema = ValidatePostgresConnectionCredentialsSchema.and( - GenericCreateAppConnectionFieldsSchema(AppConnection.Postgres, { supportsPlatformManagedCredentials: true }) + GenericCreateAppConnectionFieldsSchema(AppConnection.Postgres, { + supportsPlatformManagedCredentials: true, + supportsGateways: true + }) ); export const UpdatePostgresConnectionSchema = z @@ -56,7 +59,12 @@ export const UpdatePostgresConnectionSchema = z AppConnections.UPDATE(AppConnection.Postgres).credentials ) }) - .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.Postgres, { supportsPlatformManagedCredentials: true })); + .and( + GenericUpdateAppConnectionFieldsSchema(AppConnection.Postgres, { + supportsPlatformManagedCredentials: true, + supportsGateways: true + }) + ); export const PostgresConnectionListItemSchema = z.object({ name: z.literal("PostgreSQL"), diff --git a/backend/src/services/app-connection/shared/sql/sql-connection-fns.ts b/backend/src/services/app-connection/shared/sql/sql-connection-fns.ts index 33cc8257d..d9adc91dd 100644 --- a/backend/src/services/app-connection/shared/sql/sql-connection-fns.ts +++ b/backend/src/services/app-connection/shared/sql/sql-connection-fns.ts @@ -1,11 +1,13 @@ import knex, { Knex } from "knex"; import { verifyHostInputValidity } from "@app/ee/services/dynamic-secret/dynamic-secret-fns"; +import { TGatewayServiceFactory } from "@app/ee/services/gateway/gateway-service"; import { TSqlCredentialsRotationGeneratedCredentials, TSqlCredentialsRotationWithConnection } from "@app/ee/services/secret-rotation-v2/shared/sql-credentials/sql-credentials-rotation-types"; import { BadRequestError, DatabaseError } from "@app/lib/errors"; +import { GatewayProxyProtocol, withGatewayProxy } from "@app/lib/gateway"; import { alphaNumericNanoId } from "@app/lib/nanoid"; import { AppConnection } from "@app/services/app-connection/app-connection-enums"; import { TAppConnectionRaw, TSqlConnection } from "@app/services/app-connection/app-connection-types"; @@ -98,25 +100,80 @@ export const getSqlConnectionClient = async (appConnection: Pick { - const { credentials, app } = config; +export const executeWithPotentialGateway = async ( + config: TSqlConnectionConfig, + gatewayService: Pick, + operation: (client: Knex) => Promise +): Promise => { + const { credentials, app, gatewayId } = config; - let client: Knex | undefined; + if (gatewayId && gatewayService) { + const [targetHost] = await verifyHostInputValidity(credentials.host, true); + const relayDetails = await gatewayService.fnGetGatewayClientTlsByGatewayId(gatewayId); + const [relayHost, relayPort] = relayDetails.relayAddress.split(":"); + return withGatewayProxy( + async (proxyPort) => { + const client = knex({ + client: SQL_CONNECTION_CLIENT_MAP[app], + connection: { + database: credentials.database, + port: proxyPort, + host: "localhost", + user: credentials.username, + password: credentials.password, + connectionTimeoutMillis: EXTERNAL_REQUEST_TIMEOUT, + ...getConnectionConfig({ app, credentials }) + } + }); + try { + return await operation(client); + } finally { + await client.destroy(); + } + }, + { + protocol: GatewayProxyProtocol.Tcp, + targetHost, + targetPort: credentials.port, + relayHost, + relayPort: Number(relayPort), + identityId: relayDetails.identityId, + orgId: relayDetails.orgId, + tlsOptions: { + ca: relayDetails.certChain, + cert: relayDetails.certificate, + key: relayDetails.privateKey.toString() + } + } + ); + } + + // Non-gateway path + const client = await getSqlConnectionClient({ app, credentials }); try { - client = await getSqlConnectionClient({ app, credentials }); + return await operation(client); + } finally { + await client.destroy(); + } +}; - await client.raw(`Select 1`); - - return credentials; +export const validateSqlConnectionCredentials = async ( + config: TSqlConnectionConfig, + gatewayService: Pick +) => { + try { + await executeWithPotentialGateway(config, gatewayService, async (client) => { + await client.raw(`Select 1`); + }); + return config.credentials; } catch (error) { throw new BadRequestError({ message: `Unable to validate connection: ${ - (error as Error)?.message?.replaceAll(credentials.password, "********************") ?? "verify credentials" + (error as Error)?.message?.replaceAll(config.credentials.password, "********************") ?? + "verify credentials" }` }); - } finally { - await client?.destroy(); } }; @@ -132,22 +189,23 @@ export const SQL_CONNECTION_ALTER_LOGIN_STATEMENT: Record< export const transferSqlConnectionCredentialsToPlatform = async ( config: TSqlConnectionConfig, - callback: (credentials: TSqlConnectionConfig["credentials"]) => Promise + callback: (credentials: TSqlConnectionConfig["credentials"]) => Promise, + gatewayService: Pick ) => { const { credentials, app } = config; - const client = await getSqlConnectionClient({ app, credentials }); - const newPassword = alphaNumericNanoId(32); try { - return await client.transaction(async (tx) => { - await tx.raw( - ...SQL_CONNECTION_ALTER_LOGIN_STATEMENT[app]({ username: credentials.username, password: newPassword }) - ); - return callback({ - ...credentials, - password: newPassword + return await executeWithPotentialGateway(config, gatewayService, (client) => { + return client.transaction(async (tx) => { + await tx.raw( + ...SQL_CONNECTION_ALTER_LOGIN_STATEMENT[app]({ username: credentials.username, password: newPassword }) + ); + return callback({ + ...credentials, + password: newPassword + }); }); }); } catch (error) { @@ -161,7 +219,5 @@ export const transferSqlConnectionCredentialsToPlatform = async ( (error as Error)?.message?.replaceAll(newPassword, "********************") ?? "Encountered an error transferring credentials to platform" }); - } finally { - await client.destroy(); } }; diff --git a/backend/src/services/app-connection/shared/sql/sql-connection-types.ts b/backend/src/services/app-connection/shared/sql/sql-connection-types.ts index bbfe4086c..104aacfb9 100644 --- a/backend/src/services/app-connection/shared/sql/sql-connection-types.ts +++ b/backend/src/services/app-connection/shared/sql/sql-connection-types.ts @@ -1,6 +1,9 @@ import { DiscriminativePick } from "@app/lib/types"; import { TSqlConnectionInput } from "@app/services/app-connection/app-connection-types"; -export type TSqlConnectionConfig = DiscriminativePick & { +export type TSqlConnectionConfig = DiscriminativePick< + TSqlConnectionInput, + "method" | "app" | "credentials" | "gatewayId" +> & { orgId: string; }; diff --git a/backend/src/services/certificate-authority/certificate-authority-service.ts b/backend/src/services/certificate-authority/certificate-authority-service.ts index 0f30e91c3..fa0fe017f 100644 --- a/backend/src/services/certificate-authority/certificate-authority-service.ts +++ b/backend/src/services/certificate-authority/certificate-authority-service.ts @@ -1,6 +1,6 @@ import { ForbiddenError } from "@casl/ability"; -import { TableName } from "@app/db/schemas"; +import { ActionProjectType, TableName } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; @@ -100,7 +100,8 @@ export const certificateAuthorityServiceFactory = ({ actorId: actor.id, projectId, actorAuthMethod: actor.authMethod, - actorOrgId: actor.orgId + actorOrgId: actor.orgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -167,7 +168,8 @@ export const certificateAuthorityServiceFactory = ({ actorId: actor.id, projectId: certificateAuthority.projectId, actorAuthMethod: actor.authMethod, - actorOrgId: actor.orgId + actorOrgId: actor.orgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -215,7 +217,8 @@ export const certificateAuthorityServiceFactory = ({ actorId: actor.id, projectId, actorAuthMethod: actor.authMethod, - actorOrgId: actor.orgId + actorOrgId: actor.orgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -268,7 +271,8 @@ export const certificateAuthorityServiceFactory = ({ actorId: actor.id, projectId: certificateAuthority.projectId, actorAuthMethod: actor.authMethod, - actorOrgId: actor.orgId + actorOrgId: actor.orgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -341,7 +345,8 @@ export const certificateAuthorityServiceFactory = ({ actorId: actor.id, projectId: certificateAuthority.projectId, actorAuthMethod: actor.authMethod, - actorOrgId: actor.orgId + actorOrgId: actor.orgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( diff --git a/backend/src/services/certificate-authority/internal/internal-certificate-authority-service.ts b/backend/src/services/certificate-authority/internal/internal-certificate-authority-service.ts index 80201eab6..dd30cc62e 100644 --- a/backend/src/services/certificate-authority/internal/internal-certificate-authority-service.ts +++ b/backend/src/services/certificate-authority/internal/internal-certificate-authority-service.ts @@ -4,7 +4,7 @@ import * as x509 from "@peculiar/x509"; import slugify from "@sindresorhus/slugify"; import { z } from "zod"; -import { TableName, TCertificateAuthorities, TCertificateTemplates } from "@app/db/schemas"; +import { ActionProjectType, TableName, TCertificateAuthorities, TCertificateTemplates } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, @@ -150,7 +150,8 @@ export const internalCertificateAuthorityServiceFactory = ({ actorId: dto.actorId, projectId, actorAuthMethod: dto.actorAuthMethod, - actorOrgId: dto.actorOrgId + actorOrgId: dto.actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -333,7 +334,8 @@ export const internalCertificateAuthorityServiceFactory = ({ actorId, projectId: ca.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Read, @@ -357,7 +359,8 @@ export const internalCertificateAuthorityServiceFactory = ({ actorId: dto.actorId, projectId: ca.projectId, actorAuthMethod: dto.actorAuthMethod, - actorOrgId: dto.actorOrgId + actorOrgId: dto.actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -389,7 +392,8 @@ export const internalCertificateAuthorityServiceFactory = ({ actorId, projectId: ca.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -414,7 +418,8 @@ export const internalCertificateAuthorityServiceFactory = ({ actorId, projectId: ca.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -477,7 +482,8 @@ export const internalCertificateAuthorityServiceFactory = ({ actorId, projectId: ca.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -763,7 +769,8 @@ export const internalCertificateAuthorityServiceFactory = ({ actorId, projectId: ca.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -799,7 +806,8 @@ export const internalCertificateAuthorityServiceFactory = ({ actorId, projectId: ca.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -879,7 +887,8 @@ export const internalCertificateAuthorityServiceFactory = ({ actorId, projectId: ca.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -1026,7 +1035,8 @@ export const internalCertificateAuthorityServiceFactory = ({ actorId, projectId: ca.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -1197,7 +1207,8 @@ export const internalCertificateAuthorityServiceFactory = ({ actorId, projectId: ca.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -1553,7 +1564,8 @@ export const internalCertificateAuthorityServiceFactory = ({ actorId: dto.actorId, projectId: ca.projectId, actorAuthMethod: dto.actorAuthMethod, - actorOrgId: dto.actorOrgId + actorOrgId: dto.actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -1920,7 +1932,8 @@ export const internalCertificateAuthorityServiceFactory = ({ actorId, projectId: ca.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); const certificateTemplates = await certificateTemplateDAL.find({ caId }); diff --git a/backend/src/services/certificate-template/certificate-template-service.ts b/backend/src/services/certificate-template/certificate-template-service.ts index f8e1cf788..20c061bf7 100644 --- a/backend/src/services/certificate-template/certificate-template-service.ts +++ b/backend/src/services/certificate-template/certificate-template-service.ts @@ -1,7 +1,7 @@ import { ForbiddenError, subject } from "@casl/ability"; import * as x509 from "@peculiar/x509"; -import { TCertificateTemplateEstConfigsUpdate } from "@app/db/schemas"; +import { ActionProjectType, TCertificateTemplateEstConfigsUpdate } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { @@ -76,7 +76,8 @@ export const certificateTemplateServiceFactory = ({ actorId, projectId: ca.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -137,7 +138,8 @@ export const certificateTemplateServiceFactory = ({ actorId, projectId: certTemplate.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -201,7 +203,8 @@ export const certificateTemplateServiceFactory = ({ actorId, projectId: certTemplate.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -227,7 +230,8 @@ export const certificateTemplateServiceFactory = ({ actorId, projectId: certTemplate.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -268,7 +272,8 @@ export const certificateTemplateServiceFactory = ({ actorId, projectId: certTemplate.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -350,7 +355,8 @@ export const certificateTemplateServiceFactory = ({ actorId, projectId: certTemplate.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -429,7 +435,8 @@ export const certificateTemplateServiceFactory = ({ actorId: dto.actorId, projectId: certTemplate.projectId, actorAuthMethod: dto.actorAuthMethod, - actorOrgId: dto.actorOrgId + actorOrgId: dto.actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( diff --git a/backend/src/services/certificate/certificate-service.ts b/backend/src/services/certificate/certificate-service.ts index 541bddac7..de6da16ee 100644 --- a/backend/src/services/certificate/certificate-service.ts +++ b/backend/src/services/certificate/certificate-service.ts @@ -1,6 +1,7 @@ import { ForbiddenError } from "@casl/ability"; import * as x509 from "@peculiar/x509"; +import { ActionProjectType } from "@app/db/schemas"; import { TCertificateAuthorityCrlDALFactory } from "@app/ee/services/certificate-authority-crl/certificate-authority-crl-dal"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { @@ -79,7 +80,8 @@ export const certificateServiceFactory = ({ actorId, projectId: cert.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -109,7 +111,8 @@ export const certificateServiceFactory = ({ actorId, projectId: cert.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -142,7 +145,8 @@ export const certificateServiceFactory = ({ actorId, projectId: cert.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -191,7 +195,8 @@ export const certificateServiceFactory = ({ actorId, projectId: ca.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -239,7 +244,8 @@ export const certificateServiceFactory = ({ actorId, projectId: cert.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -319,7 +325,8 @@ export const certificateServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -523,7 +530,8 @@ export const certificateServiceFactory = ({ actorId, projectId: cert.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( diff --git a/backend/src/services/cmek/cmek-service.ts b/backend/src/services/cmek/cmek-service.ts index 7817266b3..f913f972f 100644 --- a/backend/src/services/cmek/cmek-service.ts +++ b/backend/src/services/cmek/cmek-service.ts @@ -1,5 +1,6 @@ import { ForbiddenError } from "@casl/ability"; +import { ActionProjectType } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionCmekActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { SigningAlgorithm } from "@app/lib/crypto/sign"; @@ -38,7 +39,8 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService }: TC actorId: actor.id, projectId, actorAuthMethod: actor.authMethod, - actorOrgId: actor.orgId + actorOrgId: actor.orgId, + actionProjectType: ActionProjectType.KMS }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Create, ProjectPermissionSub.Cmek); @@ -77,7 +79,8 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService }: TC actorId: actor.id, projectId: key.projectId, actorAuthMethod: actor.authMethod, - actorOrgId: actor.orgId + actorOrgId: actor.orgId, + actionProjectType: ActionProjectType.KMS }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Edit, ProjectPermissionSub.Cmek); @@ -113,7 +116,8 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService }: TC actorId: actor.id, projectId: key.projectId, actorAuthMethod: actor.authMethod, - actorOrgId: actor.orgId + actorOrgId: actor.orgId, + actionProjectType: ActionProjectType.KMS }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Delete, ProjectPermissionSub.Cmek); @@ -129,7 +133,8 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService }: TC actorId: actor.id, projectId, actorAuthMethod: actor.authMethod, - actorOrgId: actor.orgId + actorOrgId: actor.orgId, + actionProjectType: ActionProjectType.KMS }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Read, ProjectPermissionSub.Cmek); @@ -151,7 +156,8 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService }: TC actorId: actor.id, projectId: key.projectId, actorAuthMethod: actor.authMethod, - actorOrgId: actor.orgId + actorOrgId: actor.orgId, + actionProjectType: ActionProjectType.KMS }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Read, ProjectPermissionSub.Cmek); @@ -172,7 +178,8 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService }: TC actorId: actor.id, projectId: key.projectId, actorAuthMethod: actor.authMethod, - actorOrgId: actor.orgId + actorOrgId: actor.orgId, + actionProjectType: ActionProjectType.KMS }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Read, ProjectPermissionSub.Cmek); @@ -194,7 +201,8 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService }: TC actorId: actor.id, projectId: key.projectId, actorAuthMethod: actor.authMethod, - actorOrgId: actor.orgId + actorOrgId: actor.orgId, + actionProjectType: ActionProjectType.KMS }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Encrypt, ProjectPermissionSub.Cmek); @@ -221,7 +229,8 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService }: TC actorId: actor.id, projectId: key.projectId, actorAuthMethod: actor.authMethod, - actorOrgId: actor.orgId + actorOrgId: actor.orgId, + actionProjectType: ActionProjectType.KMS }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Read, ProjectPermissionSub.Cmek); @@ -268,7 +277,8 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService }: TC actorId: actor.id, projectId: key.projectId, actorAuthMethod: actor.authMethod, - actorOrgId: actor.orgId + actorOrgId: actor.orgId, + actionProjectType: ActionProjectType.KMS }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Read, ProjectPermissionSub.Cmek); @@ -291,7 +301,8 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService }: TC actorId: actor.id, projectId: key.projectId, actorAuthMethod: actor.authMethod, - actorOrgId: actor.orgId + actorOrgId: actor.orgId, + actionProjectType: ActionProjectType.KMS }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Sign, ProjectPermissionSub.Cmek); @@ -325,7 +336,8 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService }: TC actorId: actor.id, projectId: key.projectId, actorAuthMethod: actor.authMethod, - actorOrgId: actor.orgId + actorOrgId: actor.orgId, + actionProjectType: ActionProjectType.KMS }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Verify, ProjectPermissionSub.Cmek); @@ -360,7 +372,8 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService }: TC actorId: actor.id, projectId: key.projectId, actorAuthMethod: actor.authMethod, - actorOrgId: actor.orgId + actorOrgId: actor.orgId, + actionProjectType: ActionProjectType.KMS }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Decrypt, ProjectPermissionSub.Cmek); diff --git a/backend/src/services/folder-commit/folder-commit-service.ts b/backend/src/services/folder-commit/folder-commit-service.ts index 3576f444b..470edbbba 100644 --- a/backend/src/services/folder-commit/folder-commit-service.ts +++ b/backend/src/services/folder-commit/folder-commit-service.ts @@ -2,7 +2,13 @@ import { ForbiddenError } from "@casl/ability"; import { Knex } from "knex"; -import { TSecretFolders, TSecretFolderVersions, TSecretV2TagJunctionInsert, TSecretVersionsV2 } from "@app/db/schemas"; +import { + ActionProjectType, + TSecretFolders, + TSecretFolderVersions, + TSecretV2TagJunctionInsert, + TSecretVersionsV2 +} from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionCommitsActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { getConfig } from "@app/lib/config/env"; @@ -47,6 +53,14 @@ export enum ResourceType { FOLDER = "folder" } +export type TCommitResourceChangeDTO = { + type: string; + secretVersionId?: string; + folderVersionId?: string; + isUpdate?: boolean; + folderId?: string; +}; + type TCreateCommitDTO = { actor: { type: string; @@ -57,13 +71,7 @@ type TCreateCommitDTO = { }; message?: string; folderId: string; - changes: { - type: string; - secretVersionId?: string; - folderVersionId?: string; - isUpdate?: boolean; - folderId?: string; - }[]; + changes: TCommitResourceChangeDTO[]; omitIgnoreFilter?: boolean; }; @@ -217,7 +225,8 @@ export const folderCommitServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCommitsActions.Read, ProjectPermissionSub.Commits); @@ -2060,7 +2069,8 @@ export const folderCommitServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( diff --git a/backend/src/services/group-project/group-project-service.ts b/backend/src/services/group-project/group-project-service.ts index a04d8b19f..50a08e94f 100644 --- a/backend/src/services/group-project/group-project-service.ts +++ b/backend/src/services/group-project/group-project-service.ts @@ -1,6 +1,6 @@ import { ForbiddenError } from "@casl/ability"; -import { ProjectMembershipRole, SecretKeyEncoding, TGroups } from "@app/db/schemas"; +import { ActionProjectType, ProjectMembershipRole, SecretKeyEncoding, TGroups } from "@app/db/schemas"; import { TListProjectGroupUsersDTO } from "@app/ee/services/group/group-types"; import { constructPermissionErrorMessage, @@ -78,7 +78,8 @@ export const groupProjectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionGroupActions.Create, ProjectPermissionSub.Groups); @@ -271,7 +272,8 @@ export const groupProjectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionGroupActions.Edit, ProjectPermissionSub.Groups); @@ -384,7 +386,8 @@ export const groupProjectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionGroupActions.Delete, ProjectPermissionSub.Groups); @@ -428,7 +431,8 @@ export const groupProjectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionGroupActions.Read, ProjectPermissionSub.Groups); @@ -455,7 +459,8 @@ export const groupProjectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionGroupActions.Read, ProjectPermissionSub.Groups); @@ -496,7 +501,8 @@ export const groupProjectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionGroupActions.Read, ProjectPermissionSub.Groups); diff --git a/backend/src/services/identity-aws-auth/identity-aws-auth-validators.ts b/backend/src/services/identity-aws-auth/identity-aws-auth-validators.ts index d0ef6fd88..098bdcf9a 100644 --- a/backend/src/services/identity-aws-auth/identity-aws-auth-validators.ts +++ b/backend/src/services/identity-aws-auth/identity-aws-auth-validators.ts @@ -37,7 +37,7 @@ export const validateAccountIds = z export const validatePrincipalArns = z .string() .trim() - .max(2048) + .max(4096) .default("") // Custom validation for ARN format .refine( diff --git a/backend/src/services/identity-project/identity-project-service.ts b/backend/src/services/identity-project/identity-project-service.ts index 7ee051d88..4f0964f42 100644 --- a/backend/src/services/identity-project/identity-project-service.ts +++ b/backend/src/services/identity-project/identity-project-service.ts @@ -1,6 +1,6 @@ import { ForbiddenError, subject } from "@casl/ability"; -import { ProjectMembershipRole } from "@app/db/schemas"; +import { ActionProjectType, ProjectMembershipRole } from "@app/db/schemas"; import { constructPermissionErrorMessage, validatePrivilegeChangeOperation @@ -62,7 +62,8 @@ export const identityProjectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionIdentityActions.Create, @@ -181,7 +182,8 @@ export const identityProjectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionIdentityActions.Edit, @@ -291,7 +293,8 @@ export const identityProjectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionIdentityActions.Delete, @@ -319,7 +322,8 @@ export const identityProjectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionIdentityActions.Read, @@ -352,7 +356,8 @@ export const identityProjectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan( @@ -388,7 +393,8 @@ export const identityProjectServiceFactory = ({ actorId, projectId: membership.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan( diff --git a/backend/src/services/integration-auth/integration-auth-service.ts b/backend/src/services/integration-auth/integration-auth-service.ts index 0729fcb5d..248488e9f 100644 --- a/backend/src/services/integration-auth/integration-auth-service.ts +++ b/backend/src/services/integration-auth/integration-auth-service.ts @@ -4,7 +4,13 @@ import { Octokit } from "@octokit/rest"; import { Client as OctopusClient, SpaceRepository as OctopusSpaceRepository } from "@octopusdeploy/api-client"; import AWS from "aws-sdk"; -import { SecretEncryptionAlgo, SecretKeyEncoding, TIntegrationAuths, TIntegrationAuthsInsert } from "@app/db/schemas"; +import { + ActionProjectType, + SecretEncryptionAlgo, + SecretKeyEncoding, + TIntegrationAuths, + TIntegrationAuthsInsert +} from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { getConfig } from "@app/lib/config/env"; @@ -97,7 +103,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const authorizations = await integrationAuthDAL.find({ projectId }); @@ -115,7 +122,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: auth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); return permission.can(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations) ? auth : null; @@ -138,7 +146,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); return integrationAuth; @@ -163,7 +172,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Integrations); @@ -281,7 +291,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Integrations); @@ -435,7 +446,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Integrations); @@ -732,7 +744,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); @@ -766,7 +779,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); @@ -796,7 +810,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId); @@ -837,7 +852,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId); @@ -865,7 +881,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId); @@ -939,7 +956,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId); @@ -986,7 +1004,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId); @@ -1020,7 +1039,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId); @@ -1078,7 +1098,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId); @@ -1114,7 +1135,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId); @@ -1155,7 +1177,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId); @@ -1195,7 +1218,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId); @@ -1235,7 +1259,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId); @@ -1274,7 +1299,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId); @@ -1314,7 +1340,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId); @@ -1382,7 +1409,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId); @@ -1456,7 +1484,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId); @@ -1506,7 +1535,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId); @@ -1554,7 +1584,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId); @@ -1622,7 +1653,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId); @@ -1663,7 +1695,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId); @@ -1775,7 +1808,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Integrations); @@ -1798,7 +1832,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Integrations); @@ -1831,7 +1866,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(sourcePermission).throwUnlessCan( @@ -1844,7 +1880,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(targetPermission).throwUnlessCan( @@ -1877,7 +1914,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); @@ -1911,7 +1949,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId); @@ -1951,7 +1990,8 @@ export const integrationAuthServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId); diff --git a/backend/src/services/integration/integration-service.ts b/backend/src/services/integration/integration-service.ts index e03ca1e8f..2ef8615eb 100644 --- a/backend/src/services/integration/integration-service.ts +++ b/backend/src/services/integration/integration-service.ts @@ -1,5 +1,6 @@ import { ForbiddenError } from "@casl/ability"; +import { ActionProjectType } from "@app/db/schemas"; import { throwIfMissingSecretReadValueOrDescribePermission } from "@app/ee/services/permission/permission-fns"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { @@ -90,7 +91,8 @@ export const integrationServiceFactory = ({ actorId, projectId: integrationAuth.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Integrations); @@ -165,7 +167,8 @@ export const integrationServiceFactory = ({ actorId, projectId: integration.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Integrations); @@ -228,7 +231,8 @@ export const integrationServiceFactory = ({ actorId, projectId: integration.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); @@ -255,7 +259,8 @@ export const integrationServiceFactory = ({ actorId, projectId: integration.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); @@ -297,7 +302,8 @@ export const integrationServiceFactory = ({ actorId, projectId: integration.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Integrations); @@ -333,7 +339,8 @@ export const integrationServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); @@ -352,7 +359,8 @@ export const integrationServiceFactory = ({ actorId, projectId: integration.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); diff --git a/backend/src/services/org/org-service.ts b/backend/src/services/org/org-service.ts index cdbe9550f..5f60bfe1e 100644 --- a/backend/src/services/org/org-service.ts +++ b/backend/src/services/org/org-service.ts @@ -3,6 +3,7 @@ import slugify from "@sindresorhus/slugify"; import { Knex } from "knex"; import { + ActionProjectType, OrgMembershipRole, OrgMembershipStatus, ProjectMembershipRole, @@ -981,7 +982,8 @@ export const orgServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(projectPermission).throwUnlessCan( ProjectPermissionMemberActions.Create, diff --git a/backend/src/services/pki-alert/pki-alert-service.ts b/backend/src/services/pki-alert/pki-alert-service.ts index 8b348085f..c35bfbd16 100644 --- a/backend/src/services/pki-alert/pki-alert-service.ts +++ b/backend/src/services/pki-alert/pki-alert-service.ts @@ -1,5 +1,6 @@ import { ForbiddenError } from "@casl/ability"; +import { ActionProjectType } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { ForbiddenRequestError, NotFoundError } from "@app/lib/errors"; @@ -78,7 +79,8 @@ export const pkiAlertServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.PkiAlerts); @@ -107,7 +109,8 @@ export const pkiAlertServiceFactory = ({ actorId, projectId: alert.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.PkiAlerts); @@ -133,7 +136,8 @@ export const pkiAlertServiceFactory = ({ actorId, projectId: alert.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.PkiAlerts); @@ -165,7 +169,8 @@ export const pkiAlertServiceFactory = ({ actorId, projectId: alert.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.PkiAlerts); diff --git a/backend/src/services/pki-collection/pki-collection-service.ts b/backend/src/services/pki-collection/pki-collection-service.ts index 7c89ce255..0f3c26556 100644 --- a/backend/src/services/pki-collection/pki-collection-service.ts +++ b/backend/src/services/pki-collection/pki-collection-service.ts @@ -1,6 +1,6 @@ import { ForbiddenError } from "@casl/ability"; -import { TPkiCollectionItems } from "@app/db/schemas"; +import { ActionProjectType, TPkiCollectionItems } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; @@ -55,7 +55,8 @@ export const pkiCollectionServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -87,7 +88,8 @@ export const pkiCollectionServiceFactory = ({ actorId, projectId: pkiCollection.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.PkiCollections); @@ -111,7 +113,8 @@ export const pkiCollectionServiceFactory = ({ actorId, projectId: pkiCollection.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.PkiCollections); @@ -138,7 +141,8 @@ export const pkiCollectionServiceFactory = ({ actorId, projectId: pkiCollection.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -167,7 +171,8 @@ export const pkiCollectionServiceFactory = ({ actorId, projectId: pkiCollection.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.PkiCollections); @@ -210,7 +215,8 @@ export const pkiCollectionServiceFactory = ({ actorId, projectId: pkiCollection.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -297,7 +303,8 @@ export const pkiCollectionServiceFactory = ({ actorId, projectId: pkiCollection.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( diff --git a/backend/src/services/pki-subscriber/pki-subscriber-service.ts b/backend/src/services/pki-subscriber/pki-subscriber-service.ts index 245337296..a3e6ec78c 100644 --- a/backend/src/services/pki-subscriber/pki-subscriber-service.ts +++ b/backend/src/services/pki-subscriber/pki-subscriber-service.ts @@ -2,6 +2,7 @@ import { ForbiddenError, subject } from "@casl/ability"; import * as x509 from "@peculiar/x509"; +import { ActionProjectType } from "@app/db/schemas"; import { TCertificateAuthorityCrlDALFactory } from "@app/ee/services/certificate-authority-crl/certificate-authority-crl-dal"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { @@ -119,7 +120,8 @@ export const pkiSubscriberServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -181,7 +183,8 @@ export const pkiSubscriberServiceFactory = ({ actorId, projectId: subscriber.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -234,7 +237,8 @@ export const pkiSubscriberServiceFactory = ({ actorId, projectId: subscriber.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -296,7 +300,8 @@ export const pkiSubscriberServiceFactory = ({ actorId, projectId: subscriber.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -332,7 +337,8 @@ export const pkiSubscriberServiceFactory = ({ actorId, projectId: subscriber.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -387,7 +393,8 @@ export const pkiSubscriberServiceFactory = ({ actorId, projectId: subscriber.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -433,7 +440,8 @@ export const pkiSubscriberServiceFactory = ({ actorId, projectId: ca.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -691,7 +699,8 @@ export const pkiSubscriberServiceFactory = ({ actorId, projectId: subscriber.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -738,7 +747,8 @@ export const pkiSubscriberServiceFactory = ({ actorId, projectId: subscriber.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( diff --git a/backend/src/services/pki-templates/pki-templates-service.ts b/backend/src/services/pki-templates/pki-templates-service.ts index 98469c157..e648ab88f 100644 --- a/backend/src/services/pki-templates/pki-templates-service.ts +++ b/backend/src/services/pki-templates/pki-templates-service.ts @@ -3,6 +3,7 @@ import { ForbiddenError, subject } from "@casl/ability"; import * as x509 from "@peculiar/x509"; import RE2 from "re2"; +import { ActionProjectType } from "@app/db/schemas"; import { TCertificateAuthorityCrlDALFactory } from "@app/ee/services/certificate-authority-crl/certificate-authority-crl-dal"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { @@ -118,7 +119,8 @@ export const pkiTemplatesServiceFactory = ({ actorId, projectId: ca.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -170,7 +172,8 @@ export const pkiTemplatesServiceFactory = ({ actorId, projectId: certTemplate.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -233,7 +236,8 @@ export const pkiTemplatesServiceFactory = ({ actorId, projectId: certTemplate.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -265,7 +269,8 @@ export const pkiTemplatesServiceFactory = ({ actorId, projectId: certTemplate.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -290,7 +295,8 @@ export const pkiTemplatesServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); const certTemplate = await pkiTemplatesDAL.find({ projectId }, { limit, offset, count: true }); @@ -332,7 +338,8 @@ export const pkiTemplatesServiceFactory = ({ actorId, projectId: certTemplate.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -378,7 +385,8 @@ export const pkiTemplatesServiceFactory = ({ actorId, projectId: certTemplate.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( diff --git a/backend/src/services/project-bot/project-bot-service.ts b/backend/src/services/project-bot/project-bot-service.ts index 76c40dff7..c6625c28a 100644 --- a/backend/src/services/project-bot/project-bot-service.ts +++ b/backend/src/services/project-bot/project-bot-service.ts @@ -1,6 +1,6 @@ import { ForbiddenError } from "@casl/ability"; -import { ProjectVersion } from "@app/db/schemas"; +import { ActionProjectType, ProjectVersion } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { crypto } from "@app/lib/crypto/cryptography"; @@ -45,7 +45,8 @@ export const projectBotServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); @@ -115,7 +116,8 @@ export const projectBotServiceFactory = ({ actorId, projectId: bot.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Integrations); diff --git a/backend/src/services/project-env/project-env-service.ts b/backend/src/services/project-env/project-env-service.ts index 6773ee600..9a82a6bbe 100644 --- a/backend/src/services/project-env/project-env-service.ts +++ b/backend/src/services/project-env/project-env-service.ts @@ -1,5 +1,6 @@ import { ForbiddenError } from "@casl/ability"; +import { ActionProjectType } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; @@ -46,7 +47,8 @@ export const projectEnvServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Environments); @@ -134,7 +136,8 @@ export const projectEnvServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Environments); @@ -197,7 +200,8 @@ export const projectEnvServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Environments); @@ -252,7 +256,8 @@ export const projectEnvServiceFactory = ({ actorId, projectId: environment.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Environments); diff --git a/backend/src/services/project-key/project-key-service.ts b/backend/src/services/project-key/project-key-service.ts index c4eae9e2e..a884d25bc 100644 --- a/backend/src/services/project-key/project-key-service.ts +++ b/backend/src/services/project-key/project-key-service.ts @@ -1,5 +1,6 @@ import { ForbiddenError } from "@casl/ability"; +import { ActionProjectType } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionMemberActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { BadRequestError } from "@app/lib/errors"; @@ -36,7 +37,8 @@ export const projectKeyServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionMemberActions.Edit, ProjectPermissionSub.Member); @@ -65,7 +67,8 @@ export const projectKeyServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); const latestKey = await projectKeyDAL.findLatestProjectKey(actorId, projectId); return latestKey; @@ -83,7 +86,8 @@ export const projectKeyServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionMemberActions.Read, ProjectPermissionSub.Member); return projectKeyDAL.findAllProjectUserPubKeys(projectId); diff --git a/backend/src/services/project-membership/project-membership-service.ts b/backend/src/services/project-membership/project-membership-service.ts index 9cef4dabf..b9e502922 100644 --- a/backend/src/services/project-membership/project-membership-service.ts +++ b/backend/src/services/project-membership/project-membership-service.ts @@ -1,7 +1,7 @@ /* eslint-disable no-await-in-loop */ import { ForbiddenError } from "@casl/ability"; -import { ProjectMembershipRole, ProjectVersion, TableName } from "@app/db/schemas"; +import { ActionProjectType, ProjectMembershipRole, ProjectVersion, TableName } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { constructPermissionErrorMessage, @@ -90,7 +90,8 @@ export const projectMembershipServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionMemberActions.Read, ProjectPermissionSub.Member); @@ -133,7 +134,8 @@ export const projectMembershipServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionMemberActions.Read, ProjectPermissionSub.Member); @@ -155,7 +157,8 @@ export const projectMembershipServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionMemberActions.Read, ProjectPermissionSub.Member); @@ -181,7 +184,8 @@ export const projectMembershipServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionMemberActions.Create, ProjectPermissionSub.Member); const orgMembers = await orgDAL.findMembership({ @@ -261,7 +265,8 @@ export const projectMembershipServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionMemberActions.Edit, ProjectPermissionSub.Member); @@ -370,7 +375,8 @@ export const projectMembershipServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionMemberActions.Delete, ProjectPermissionSub.Member); @@ -412,7 +418,8 @@ export const projectMembershipServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionMemberActions.Delete, ProjectPermissionSub.Member); diff --git a/backend/src/services/project-role/project-role-fns.ts b/backend/src/services/project-role/project-role-fns.ts index bf5044f47..4dfcf960b 100644 --- a/backend/src/services/project-role/project-role-fns.ts +++ b/backend/src/services/project-role/project-role-fns.ts @@ -11,7 +11,7 @@ import { } from "@app/ee/services/permission/default-roles"; import { TGetPredefinedRolesDTO } from "@app/services/project-role/project-role-types"; -export const getPredefinedRoles = ({ projectId, roleFilter }: TGetPredefinedRolesDTO) => { +export const getPredefinedRoles = ({ projectId, projectType, roleFilter }: TGetPredefinedRolesDTO) => { return [ { id: uuidv4(), @@ -75,5 +75,5 @@ export const getPredefinedRoles = ({ projectId, roleFilter }: TGetPredefinedRole createdAt: new Date(), updatedAt: new Date() } - ].filter(({ slug }) => !roleFilter || roleFilter === slug); + ].filter(({ slug, type }) => (type ? type === projectType : true) && (!roleFilter || roleFilter === slug)); }; diff --git a/backend/src/services/project-role/project-role-service.ts b/backend/src/services/project-role/project-role-service.ts index 76613805e..dd0eecc68 100644 --- a/backend/src/services/project-role/project-role-service.ts +++ b/backend/src/services/project-role/project-role-service.ts @@ -2,7 +2,7 @@ import { ForbiddenError, MongoAbility, RawRuleOf } from "@casl/ability"; import { PackRule, packRules, unpackRules } from "@casl/ability/extra"; import { requestContext } from "@fastify/request-context"; -import { ProjectMembershipRole, TableName, TProjects } from "@app/db/schemas"; +import { ActionProjectType, ProjectMembershipRole, ProjectType, TableName, TProjects } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, @@ -71,7 +71,8 @@ export const projectRoleServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Role); const existingRole = await projectRoleDAL.findOne({ slug: data.slug, projectId }); @@ -111,12 +112,14 @@ export const projectRoleServiceFactory = ({ actorId, projectId: project.id, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Role); if (roleSlug !== "custom" && Object.values(ProjectMembershipRole).includes(roleSlug as ProjectMembershipRole)) { const [predefinedRole] = getPredefinedRoles({ projectId: project.id, + projectType: project.type as ProjectType, roleFilter: roleSlug as ProjectMembershipRole }); @@ -139,7 +142,8 @@ export const projectRoleServiceFactory = ({ actorId, projectId: projectRole.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Role); @@ -169,7 +173,8 @@ export const projectRoleServiceFactory = ({ actorId, projectId: projectRole.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Role); @@ -210,14 +215,18 @@ export const projectRoleServiceFactory = ({ actorId, projectId: project.id, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Role); const customRoles = await projectRoleDAL.find( { projectId: project.id }, { sort: [[`${TableName.ProjectRoles}.slug` as "slug", "asc"]] } ); - const roles = [...getPredefinedRoles({ projectId: project.id }), ...(customRoles || [])]; + const roles = [ + ...getPredefinedRoles({ projectId: project.id, projectType: project.type as ProjectType }), + ...(customRoles || []) + ]; return roles; }; @@ -233,7 +242,8 @@ export const projectRoleServiceFactory = ({ actorId: userId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); // just to satisfy ts if (!("roles" in membership)) throw new BadRequestError({ message: "Service token not allowed" }); diff --git a/backend/src/services/project-role/project-role-types.ts b/backend/src/services/project-role/project-role-types.ts index 37395a9a7..508623a0c 100644 --- a/backend/src/services/project-role/project-role-types.ts +++ b/backend/src/services/project-role/project-role-types.ts @@ -1,4 +1,4 @@ -import { ProjectMembershipRole, TOrgRolesUpdate, TProjectRolesInsert } from "@app/db/schemas"; +import { ProjectMembershipRole, ProjectType, TOrgRolesUpdate, TProjectRolesInsert } from "@app/db/schemas"; import { TProjectPermission } from "@app/lib/types"; export enum ProjectRoleServiceIdentifierType { @@ -37,5 +37,6 @@ export type TListRolesDTO = { export type TGetPredefinedRolesDTO = { projectId: string; + projectType: ProjectType; roleFilter?: ProjectMembershipRole; }; diff --git a/backend/src/services/project/project-dal.ts b/backend/src/services/project/project-dal.ts index bd008a5be..2766db379 100644 --- a/backend/src/services/project/project-dal.ts +++ b/backend/src/services/project/project-dal.ts @@ -3,6 +3,7 @@ import { Knex } from "knex"; import { TDbClient } from "@app/db"; import { ProjectsSchema, + ProjectType, ProjectUpgradeStatus, ProjectVersion, SortDirection, @@ -21,12 +22,17 @@ export type TProjectDALFactory = ReturnType; export const projectDALFactory = (db: TDbClient) => { const projectOrm = ormify(db, TableName.Project); - const findIdentityProjects = async (identityId: string, orgId: string) => { + const findIdentityProjects = async (identityId: string, orgId: string, projectType?: ProjectType) => { try { const workspaces = await db(TableName.IdentityProjectMembership) .where({ identityId }) .join(TableName.Project, `${TableName.IdentityProjectMembership}.projectId`, `${TableName.Project}.id`) .where(`${TableName.Project}.orgId`, orgId) + .andWhere((qb) => { + if (projectType) { + void qb.where(`${TableName.Project}.type`, projectType); + } + }) .leftJoin(TableName.Environment, `${TableName.Environment}.projectId`, `${TableName.Project}.id`) .select( selectAllTableCols(TableName.Project), @@ -66,13 +72,18 @@ export const projectDALFactory = (db: TDbClient) => { } }; - const findUserProjects = async (userId: string, orgId: string) => { + const findUserProjects = async (userId: string, orgId: string, projectType?: ProjectType) => { try { const workspaces = await db .replicaNode()(TableName.ProjectMembership) .where({ userId }) .join(TableName.Project, `${TableName.ProjectMembership}.projectId`, `${TableName.Project}.id`) .where(`${TableName.Project}.orgId`, orgId) + .andWhere((qb) => { + if (projectType) { + void qb.where(`${TableName.Project}.type`, projectType); + } + }) .leftJoin(TableName.Environment, `${TableName.Environment}.projectId`, `${TableName.Project}.id`) .select( selectAllTableCols(TableName.Project), @@ -92,6 +103,11 @@ export const projectDALFactory = (db: TDbClient) => { .whereIn("groupId", groups) .join(TableName.Project, `${TableName.GroupProjectMembership}.projectId`, `${TableName.Project}.id`) .where(`${TableName.Project}.orgId`, orgId) + .andWhere((qb) => { + if (projectType) { + void qb.where(`${TableName.Project}.type`, projectType); + } + }) .whereNotIn( `${TableName.Project}.id`, workspaces.map(({ id }) => id) @@ -161,12 +177,17 @@ export const projectDALFactory = (db: TDbClient) => { } }; - const findAllProjectsByIdentity = async (identityId: string) => { + const findAllProjectsByIdentity = async (identityId: string, projectType?: ProjectType) => { try { const workspaces = await db .replicaNode()(TableName.IdentityProjectMembership) .where({ identityId }) .join(TableName.Project, `${TableName.IdentityProjectMembership}.projectId`, `${TableName.Project}.id`) + .andWhere((qb) => { + if (projectType) { + void qb.where(`${TableName.Project}.type`, projectType); + } + }) .leftJoin(TableName.Environment, `${TableName.Environment}.projectId`, `${TableName.Project}.id`) .select( selectAllTableCols(TableName.Project), @@ -372,6 +393,7 @@ export const projectDALFactory = (db: TDbClient) => { orgId: string; actor: ActorType; actorId: string; + type?: ProjectType; limit?: number; offset?: number; name?: string; @@ -426,6 +448,9 @@ export const projectDALFactory = (db: TDbClient) => { void query.orderBy([{ column: `${TableName.Project}.name`, order: sortDir }]); } + if (dto.type) { + void query.where(`${TableName.Project}.type`, dto.type); + } if (dto.name) { void query.whereILike(`${TableName.Project}.name`, `%${dto.name}%`); } diff --git a/backend/src/services/project/project-service.ts b/backend/src/services/project/project-service.ts index 75c8cdd25..3a8b2b132 100644 --- a/backend/src/services/project/project-service.ts +++ b/backend/src/services/project/project-service.ts @@ -1,7 +1,14 @@ import { ForbiddenError, subject } from "@casl/ability"; import slugify from "@sindresorhus/slugify"; -import { ProjectMembershipRole, ProjectVersion, TableName, TProjectEnvironments } from "@app/db/schemas"; +import { + ActionProjectType, + ProjectMembershipRole, + ProjectType, + ProjectVersion, + TableName, + TProjectEnvironments +} from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; import { throwIfMissingSecretReadValueOrDescribePermission } from "@app/ee/services/permission/permission-fns"; @@ -242,7 +249,8 @@ export const projectServiceFactory = ({ kmsKeyId, tx: trx, createDefaultEnvs = true, - template = InfisicalProjectTemplate.Default + template = InfisicalProjectTemplate.Default, + type = ProjectType.SecretManager }: TCreateProjectDTO) => { const organization = await orgDAL.findOne({ id: actorOrgId }); const { permission, membership: orgMembership } = await permissionService.getOrgPermission( @@ -258,7 +266,11 @@ export const projectServiceFactory = ({ await tx.raw("SELECT pg_advisory_xact_lock(?)", [PgSqlLock.CreateProject(organization.id)]); const plan = await licenseService.getPlan(organization.id); - if (plan.workspaceLimit !== null && plan.workspacesUsed >= plan.workspaceLimit) { + if ( + plan.workspaceLimit !== null && + plan.workspacesUsed >= plan.workspaceLimit && + type === ProjectType.SecretManager + ) { // case: limit imposed on number of workspaces allowed // case: number of workspaces used exceeds the number of workspaces allowed throw new BadRequestError({ @@ -295,6 +307,7 @@ export const projectServiceFactory = ({ const project = await projectDAL.create( { name: workspaceName, + type, description: workspaceDescription, orgId: organization.id, slug: projectSlug || slugify(`${workspaceName}-${alphaNumericNanoId(4)}`), @@ -305,14 +318,16 @@ export const projectServiceFactory = ({ tx ); - await bootstrapSshProject({ - projectId: project.id, - sshCertificateAuthorityDAL, - sshCertificateAuthoritySecretDAL, - kmsService, - projectSshConfigDAL, - tx - }); + if (type === ProjectType.SSH) { + await bootstrapSshProject({ + projectId: project.id, + sshCertificateAuthorityDAL, + sshCertificateAuthoritySecretDAL, + kmsService, + projectSshConfigDAL, + tx + }); + } // set ghost user as admin of project const projectMembership = await projectMembershipDAL.create( @@ -512,7 +527,8 @@ export const projectServiceFactory = ({ actorId, projectId: project.id, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Project); @@ -570,11 +586,11 @@ export const projectServiceFactory = ({ return deletedProject; }; - const getProjects = async ({ actorId, actor, includeRoles, actorAuthMethod, actorOrgId }: TListProjectsDTO) => { + const getProjects = async ({ actorId, actor, includeRoles, actorAuthMethod, actorOrgId, type }: TListProjectsDTO) => { const workspaces = actor === ActorType.IDENTITY - ? await projectDAL.findIdentityProjects(actorId, actorOrgId) - : await projectDAL.findUserProjects(actorId, actorOrgId); + ? await projectDAL.findIdentityProjects(actorId, actorOrgId, type) + : await projectDAL.findUserProjects(actorId, actorOrgId, type); if (includeRoles) { const { permission } = await permissionService.getUserOrgPermission( @@ -598,7 +614,10 @@ export const projectServiceFactory = ({ workspaces.map(async (workspace) => { return { ...workspace, - roles: [...(workspaceMappedToRoles[workspace.id] || []), ...getPredefinedRoles({ projectId: workspace.id })] + roles: [ + ...(workspaceMappedToRoles[workspace.id] || []), + ...getPredefinedRoles({ projectId: workspace.id, projectType: workspace.type as ProjectType }) + ] }; }) ); @@ -617,7 +636,8 @@ export const projectServiceFactory = ({ actorId, projectId: project.id, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); return project; }; @@ -630,7 +650,8 @@ export const projectServiceFactory = ({ actorId, projectId: project.id, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Settings); @@ -674,7 +695,8 @@ export const projectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Settings); @@ -699,7 +721,8 @@ export const projectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Settings); @@ -728,7 +751,8 @@ export const projectServiceFactory = ({ actorId, projectId: project.id, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); if (!hasRole(ProjectMembershipRole.Admin)) @@ -759,7 +783,8 @@ export const projectServiceFactory = ({ actorId, projectId: project.id, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); if (!hasRole(ProjectMembershipRole.Admin)) { @@ -791,7 +816,8 @@ export const projectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Settings); @@ -812,7 +838,8 @@ export const projectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Project); @@ -882,7 +909,8 @@ export const projectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.DescribeSecret); @@ -920,7 +948,8 @@ export const projectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -966,7 +995,8 @@ export const projectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -1010,7 +1040,8 @@ export const projectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.PkiAlerts); @@ -1037,7 +1068,8 @@ export const projectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.PkiCollections); @@ -1064,7 +1096,8 @@ export const projectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); const allowedSubscribers = []; @@ -1102,7 +1135,8 @@ export const projectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager }); const certificateTemplates = await certificateTemplateDAL.getCertTemplatesByProjectId(projectId); @@ -1132,7 +1166,8 @@ export const projectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan( @@ -1165,7 +1200,8 @@ export const projectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); const allowedHosts = []; @@ -1204,7 +1240,8 @@ export const projectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SshHostGroups); @@ -1231,7 +1268,8 @@ export const projectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SshCertificates); @@ -1269,7 +1307,8 @@ export const projectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan( @@ -1303,7 +1342,8 @@ export const projectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Kms); @@ -1330,7 +1370,8 @@ export const projectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Kms); @@ -1359,7 +1400,8 @@ export const projectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Kms); @@ -1381,7 +1423,8 @@ export const projectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); if (!membership) { @@ -1413,7 +1456,8 @@ export const projectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Settings); @@ -1452,7 +1496,8 @@ export const projectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SSH }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Settings); @@ -1535,7 +1580,8 @@ export const projectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Settings); @@ -1607,7 +1653,8 @@ export const projectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Settings); @@ -1684,7 +1731,8 @@ export const projectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Settings); @@ -1807,7 +1855,8 @@ export const projectServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Settings); @@ -1835,7 +1884,15 @@ export const projectServiceFactory = ({ }); }; - const searchProjects = async ({ name, offset, permission, limit, orderBy, orderDirection }: TSearchProjectsDTO) => { + const searchProjects = async ({ + name, + offset, + permission, + limit, + type, + orderBy, + orderDirection + }: TSearchProjectsDTO) => { // check user belong to org await permissionService.getOrgPermission( permission.type, @@ -1849,6 +1906,7 @@ export const projectServiceFactory = ({ limit, offset, name, + type, orgId: permission.orgId, actor: permission.type, actorId: permission.id, @@ -1872,7 +1930,7 @@ export const projectServiceFactory = ({ actor: permission.type, actorId: permission.id, projectId, - + actionProjectType: ActionProjectType.Any, actorAuthMethod: permission.authMethod, actorOrgId: permission.orgId }) diff --git a/backend/src/services/project/project-types.ts b/backend/src/services/project/project-types.ts index 5d4578194..b8c37a858 100644 --- a/backend/src/services/project/project-types.ts +++ b/backend/src/services/project/project-types.ts @@ -108,7 +108,7 @@ export type TDeleteProjectDTO = { export type TListProjectsDTO = { includeRoles: boolean; - type?: ProjectType | "all"; + type?: ProjectType; } & Omit; export type TUpgradeProjectDTO = { diff --git a/backend/src/services/secret-blind-index/secret-blind-index-service.ts b/backend/src/services/secret-blind-index/secret-blind-index-service.ts index c8fed2a2b..a19ce8b88 100644 --- a/backend/src/services/secret-blind-index/secret-blind-index-service.ts +++ b/backend/src/services/secret-blind-index/secret-blind-index-service.ts @@ -1,4 +1,4 @@ -import { ProjectMembershipRole } from "@app/db/schemas"; +import { ActionProjectType, ProjectMembershipRole } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ForbiddenRequestError, NotFoundError } from "@app/lib/errors"; @@ -36,7 +36,8 @@ export const secretBlindIndexServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const secretCount = await secretBlindIndexDAL.countOfSecretsWithNullSecretBlindIndex(projectId); @@ -55,7 +56,8 @@ export const secretBlindIndexServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); if (!hasRole(ProjectMembershipRole.Admin)) { throw new ForbiddenRequestError({ message: "Insufficient privileges, user must be admin" }); @@ -78,7 +80,8 @@ export const secretBlindIndexServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); if (!hasRole(ProjectMembershipRole.Admin)) { throw new ForbiddenRequestError({ message: "Insufficient privileges, user must be admin" }); diff --git a/backend/src/services/secret-folder/secret-folder-service.ts b/backend/src/services/secret-folder/secret-folder-service.ts index e8d0b05e5..a60d29348 100644 --- a/backend/src/services/secret-folder/secret-folder-service.ts +++ b/backend/src/services/secret-folder/secret-folder-service.ts @@ -1,8 +1,10 @@ +/* eslint-disable no-await-in-loop */ import { ForbiddenError, subject } from "@casl/ability"; +import { Knex } from "knex"; import path from "path"; import { v4 as uuidv4, validate as uuidValidate } from "uuid"; -import { TProjectEnvironments, TSecretFolders, TSecretFoldersInsert } from "@app/db/schemas"; +import { ActionProjectType, TProjectEnvironments, TSecretFolders, TSecretFoldersInsert } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { TSecretApprovalPolicyServiceFactory } from "@app/ee/services/secret-approval-policy/secret-approval-policy-service"; @@ -12,14 +14,21 @@ import { BadRequestError, NotFoundError } from "@app/lib/errors"; import { OrderByDirection, OrgServiceActor } from "@app/lib/types"; import { buildFolderPath } from "@app/services/secret-folder/secret-folder-fns"; -import { ChangeType, CommitType, TFolderCommitServiceFactory } from "../folder-commit/folder-commit-service"; +import { + ChangeType, + CommitType, + TCommitResourceChangeDTO, + TFolderCommitServiceFactory +} from "../folder-commit/folder-commit-service"; import { TProjectDALFactory } from "../project/project-dal"; import { TProjectEnvDALFactory } from "../project-env/project-env-dal"; import { TSecretV2BridgeDALFactory } from "../secret-v2-bridge/secret-v2-bridge-dal"; import { TSecretFolderDALFactory } from "./secret-folder-dal"; import { TCreateFolderDTO, + TCreateManyFoldersDTO, TDeleteFolderDTO, + TDeleteManyFoldersDTO, TGetFolderByIdDTO, TGetFolderDTO, TGetFoldersDeepByEnvsDTO, @@ -69,7 +78,8 @@ export const secretFolderServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -236,21 +246,32 @@ export const secretFolderServiceFactory = ({ actor, actorId, projectSlug, + projectId: providedProjectId, actorAuthMethod, actorOrgId, - folders - }: TUpdateManyFoldersDTO) => { - const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId); - if (!project) { - throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` }); + folders, + tx: providedTx, + commitChanges + }: TUpdateManyFoldersDTO & { tx?: Knex; commitChanges?: TCommitResourceChangeDTO[]; projectId?: string }) => { + let projectId = providedProjectId; + if (!projectId && projectSlug) { + const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId); + if (!project) { + throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` }); + } + projectId = project.id; + } + if (!projectId) { + throw new BadRequestError({ message: "Must provide either project slug or projectId" }); } const { permission } = await permissionService.getProjectPermission({ actor, actorId, - projectId: project.id, + projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); folders.forEach(({ environment, path: secretPath }) => { @@ -260,12 +281,12 @@ export const secretFolderServiceFactory = ({ ); }); - const result = await folderDAL.transaction(async (tx) => - Promise.all( + const executeBulkUpdate = async (tx: Knex) => { + return Promise.all( folders.map(async (newFolder) => { const { environment, path: secretPath, id, name, description } = newFolder; - const parentFolder = await folderDAL.findBySecretPath(project.id, environment, secretPath); + const parentFolder = await folderDAL.findBySecretPath(projectId as string, environment, secretPath, tx); if (!parentFolder) { throw new NotFoundError({ message: `Folder with path '${secretPath}' in environment with slug '${environment}' not found`, @@ -273,10 +294,10 @@ export const secretFolderServiceFactory = ({ }); } - const env = await projectEnvDAL.findOne({ projectId: project.id, slug: environment }); + const env = await projectEnvDAL.findOne({ projectId, slug: environment }, tx); if (!env) { throw new NotFoundError({ - message: `Environment with slug '${environment}' in project with ID '${project.id}' not found`, + message: `Environment with slug '${environment}' in project with ID '${projectId}' not found`, name: "UpdateManyFolders" }); } @@ -323,26 +344,34 @@ export const secretFolderServiceFactory = ({ }, tx ); - await folderCommitService.createCommit( - { - actor: { - type: actor, - metadata: { - id: actorId - } + if (commitChanges) { + commitChanges.push({ + type: CommitType.ADD, + isUpdate: true, + folderVersionId: folderVersion.id + }); + } else { + await folderCommitService.createCommit( + { + actor: { + type: actor, + metadata: { + id: actorId + } + }, + message: "Folder updated", + folderId: parentFolder.id, + changes: [ + { + type: CommitType.ADD, + isUpdate: true, + folderVersionId: folderVersion.id + } + ] }, - message: "Folder updated", - folderId: parentFolder.id, - changes: [ - { - type: CommitType.ADD, - isUpdate: true, - folderVersionId: folderVersion.id - } - ] - }, - tx - ); + tx + ); + } if (!doc) { throw new NotFoundError({ message: `Failed to update folder with id '${id}', not found`, @@ -352,13 +381,16 @@ export const secretFolderServiceFactory = ({ return { oldFolder: folder, newFolder: doc }; }) - ) - ); + ); + }; + + // Execute with provided transaction or create new one + const result = providedTx ? await executeBulkUpdate(providedTx) : await folderDAL.transaction(executeBulkUpdate); await Promise.all(result.map(async (res) => snapshotService.performSnapshot(res.newFolder.parentId as string))); return { - projectId: project.id, + projectId, newFolders: result.map((res) => res.newFolder), oldFolders: result.map((res) => res.oldFolder) }; @@ -381,7 +413,8 @@ export const secretFolderServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -582,7 +615,8 @@ export const secretFolderServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -688,7 +722,8 @@ export const secretFolderServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const env = await projectEnvDAL.findOne({ projectId, slug: environment }); @@ -756,7 +791,8 @@ export const secretFolderServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const envs = await projectEnvDAL.findBySlugs(projectId, environments); @@ -797,7 +833,8 @@ export const secretFolderServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const envs = await projectEnvDAL.findBySlugs(projectId, environments); @@ -832,7 +869,8 @@ export const secretFolderServiceFactory = ({ actorId, projectId: folder.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const [folderWithPath] = await folderDAL.findSecretPathByFolderIds(folder.projectId, [folder.id]); @@ -860,7 +898,8 @@ export const secretFolderServiceFactory = ({ actorId: actor.id, projectId, actorAuthMethod: actor.authMethod, - actorOrgId: actor.orgId + actorOrgId: actor.orgId, + actionProjectType: ActionProjectType.SecretManager }); const envs = await projectEnvDAL.findBySlugs(projectId, environments); @@ -887,7 +926,8 @@ export const secretFolderServiceFactory = ({ actorId: actor.id, projectId, actorAuthMethod: actor.authMethod, - actorOrgId: actor.orgId + actorOrgId: actor.orgId, + actionProjectType: ActionProjectType.SecretManager }); const environments = await projectEnvDAL.find({ projectId }); @@ -974,6 +1014,363 @@ export const secretFolderServiceFactory = ({ })); }; + const createManyFolders = async ({ + projectId, + actor, + actorId, + actorAuthMethod, + actorOrgId, + folders, + tx: providedTx, + commitChanges + }: TCreateManyFoldersDTO & { tx?: Knex; commitChanges?: TCommitResourceChangeDTO[] }) => { + const { permission } = await permissionService.getProjectPermission({ + actor, + actorId, + projectId, + actorAuthMethod, + actorOrgId, + actionProjectType: ActionProjectType.SecretManager + }); + + folders.forEach(({ environment, path: secretPath }) => { + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Create, + subject(ProjectPermissionSub.SecretFolders, { environment, secretPath }) + ); + }); + + const foldersByEnv = folders.reduce( + (acc, folder) => { + if (!acc[folder.environment]) { + acc[folder.environment] = []; + } + acc[folder.environment].push(folder); + return acc; + }, + {} as Record + ); + + const executeBulkCreate = async (tx: Knex) => { + const createdFolders = []; + + for (const [environment, envFolders] of Object.entries(foldersByEnv)) { + const env = await projectEnvDAL.findOne({ projectId, slug: environment }); + if (!env) { + throw new NotFoundError({ + message: `Environment with slug '${environment}' in project with ID '${projectId}' not found` + }); + } + + await tx.raw("SELECT pg_advisory_xact_lock(?)", [PgSqlLock.CreateFolder(env.id, env.projectId)]); + + for (const folderSpec of envFolders) { + const { name, path: secretPath, description } = folderSpec; + + const pathWithFolder = path.join(secretPath, name); + const parentFolder = await folderDAL.findClosestFolder(projectId, environment, pathWithFolder, tx); + + if (!parentFolder) { + throw new NotFoundError({ + message: `Parent folder for path '${pathWithFolder}' not found` + }); + } + + // Check if the exact folder already exists + const existingFolder = await folderDAL.findOne( + { + envId: env.id, + parentId: parentFolder.id, + name, + isReserved: false + }, + tx + ); + + if (existingFolder) { + createdFolders.push(existingFolder); + // eslint-disable-next-line no-continue + continue; + } + + // Handle exact folder case + if (parentFolder.path === pathWithFolder) { + createdFolders.push(parentFolder); + // eslint-disable-next-line no-continue + continue; + } + + let currentParentId = parentFolder.id; + + // Build the full path we need by processing each segment + if (parentFolder.path !== secretPath) { + const missingSegments = secretPath.substring(parentFolder.path.length).split("/").filter(Boolean); + const newFolders: TSecretFoldersInsert[] = []; + + for (const segment of missingSegments) { + const existingSegment = await folderDAL.findOne( + { + name: segment, + parentId: currentParentId, + envId: env.id, + isReserved: false + }, + tx + ); + + if (existingSegment) { + currentParentId = existingSegment.id; + } else { + const newFolder = { + name: segment, + parentId: currentParentId, + id: uuidv4(), + envId: env.id, + version: 1 + }; + + currentParentId = newFolder.id; + newFolders.push(newFolder); + } + } + + if (newFolders.length) { + const docs = await folderDAL.insertMany(newFolders, tx); + const folderVersions = await folderVersionDAL.insertMany( + docs.map((doc) => ({ + name: doc.name, + envId: doc.envId, + version: doc.version, + folderId: doc.id, + description: doc.description + })), + tx + ); + await folderCommitService.createCommit( + { + actor: { + type: actor, + metadata: { + id: actorId + } + }, + message: "Folders created (batch)", + folderId: currentParentId, + changes: folderVersions.map((fv) => ({ + type: CommitType.ADD, + folderVersionId: fv.id + })) + }, + tx + ); + } + } + + // Create the target folder + const doc = await folderDAL.create( + { name, envId: env.id, version: 1, parentId: currentParentId, description }, + tx + ); + + const folderVersion = await folderVersionDAL.create( + { + name: doc.name, + envId: doc.envId, + version: doc.version, + folderId: doc.id, + description: doc.description + }, + tx + ); + + if (commitChanges) { + commitChanges.push({ + type: CommitType.ADD, + folderVersionId: folderVersion.id + }); + } else { + await folderCommitService.createCommit( + { + actor: { + type: actor, + metadata: { + id: actorId + } + }, + message: "Folder created (batch)", + folderId: doc.id, + changes: [ + { + type: CommitType.ADD, + folderVersionId: folderVersion.id + } + ] + }, + tx + ); + } + + createdFolders.push(doc); + } + } + + return createdFolders; + }; + const result = providedTx ? await executeBulkCreate(providedTx) : await folderDAL.transaction(executeBulkCreate); + const uniqueParentIds = [...new Set(result.map((folder) => folder.parentId).filter(Boolean))]; + await Promise.all(uniqueParentIds.map((parentId) => snapshotService.performSnapshot(parentId as string))); + + return { + folders: result, + count: result.length + }; + }; + + const deleteManyFolders = async ({ + projectId, + actor, + actorId, + actorOrgId, + actorAuthMethod, + folders, + tx: providedTx, + commitChanges + }: TDeleteManyFoldersDTO & { tx?: Knex; commitChanges?: TCommitResourceChangeDTO[] }) => { + const { permission } = await permissionService.getProjectPermission({ + actor, + actorId, + projectId, + actorAuthMethod, + actorOrgId, + actionProjectType: ActionProjectType.SecretManager + }); + + folders.forEach(({ environment, path: secretPath }) => { + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Delete, + subject(ProjectPermissionSub.SecretFolders, { environment, secretPath }) + ); + }); + + const foldersByEnv = folders.reduce( + (acc, folder) => { + if (!acc[folder.environment]) { + acc[folder.environment] = []; + } + acc[folder.environment].push(folder); + return acc; + }, + {} as Record + ); + + const executeBulkDelete = async (tx: Knex) => { + const deletedFolders = []; + + for (const [environment, envFolders] of Object.entries(foldersByEnv)) { + const env = await projectEnvDAL.findOne({ projectId, slug: environment }); + if (!env) { + throw new NotFoundError({ + message: `Environment with slug '${environment}' not found` + }); + } + + for (const folderSpec of envFolders) { + const { path: secretPath, idOrName } = folderSpec; + + const parentFolder = await folderDAL.findBySecretPath(projectId, environment, secretPath, tx); + if (!parentFolder) { + throw new NotFoundError({ + message: `Folder with path '${secretPath}' in environment with slug '${environment}' not found` + }); + } + + await $checkFolderPolicy({ projectId, env, parentId: parentFolder.id, idOrName }); + + let folderToDelete = await folderDAL + .findOne({ + envId: env.id, + name: idOrName, + parentId: parentFolder.id, + isReserved: false + }) + .catch(() => null); + + if (!folderToDelete && uuidValidate(idOrName)) { + folderToDelete = await folderDAL + .findOne({ + envId: env.id, + id: idOrName, + parentId: parentFolder.id, + isReserved: false + }) + .catch(() => null); + } + + if (!folderToDelete) { + throw new NotFoundError({ + message: `Folder with ID/name '${idOrName}' not found` + }); + } + + const [doc] = await folderDAL.delete( + { + envId: env.id, + id: folderToDelete.id, + parentId: parentFolder.id, + isReserved: false + }, + tx + ); + + const folderVersions = await folderVersionDAL.findLatestFolderVersions([doc.id], tx); + + if (commitChanges) { + commitChanges.push({ + type: CommitType.DELETE, + folderVersionId: folderVersions[doc.id].id, + folderId: doc.id + }); + } else { + await folderCommitService.createCommit( + { + actor: { + type: actor, + metadata: { + id: actorId + } + }, + message: "Folder deleted (batch)", + folderId: parentFolder.id, + changes: [ + { + type: CommitType.DELETE, + folderVersionId: folderVersions[doc.id].id, + folderId: doc.id + } + ] + }, + tx + ); + } + + deletedFolders.push(doc); + } + } + + return deletedFolders; + }; + + const result = providedTx ? await executeBulkDelete(providedTx) : await folderDAL.transaction(executeBulkDelete); + + const uniqueParentIds = [...new Set(result.map((folder) => folder.parentId).filter(Boolean))]; + await Promise.all(uniqueParentIds.map((parentId) => snapshotService.performSnapshot(parentId as string))); + + return { + folders: result, + count: result.length + }; + }; + return { createFolder, updateFolder, @@ -986,6 +1383,8 @@ export const secretFolderServiceFactory = ({ getFoldersDeepByEnvs, getProjectEnvironmentsFolders, getFolderVersionsByIds, - getFolderVersions + getFolderVersions, + createManyFolders, + deleteManyFolders }; }; diff --git a/backend/src/services/secret-folder/secret-folder-types.ts b/backend/src/services/secret-folder/secret-folder-types.ts index 4008676db..ae8e2c5dc 100644 --- a/backend/src/services/secret-folder/secret-folder-types.ts +++ b/backend/src/services/secret-folder/secret-folder-types.ts @@ -1,6 +1,8 @@ import { OrderByDirection, TProjectPermission } from "@app/lib/types"; import { SecretsOrderBy } from "@app/services/secret/secret-types"; +import { ActorAuthMethod, ActorType } from "../auth/auth-type"; + export enum ReservedFolders { SecretReplication = "__reserve_replication_" } @@ -21,7 +23,7 @@ export type TUpdateFolderDTO = { } & TProjectPermission; export type TUpdateManyFoldersDTO = { - projectSlug: string; + projectSlug?: string; folders: { environment: string; path: string; @@ -62,3 +64,30 @@ export type TGetFoldersDeepByEnvsDTO = { export type TFindFoldersDeepByParentIdsDTO = { parentIds: string[]; }; + +export type TCreateManyFoldersDTO = { + projectId: string; + actor: ActorType; + actorId: string; + actorAuthMethod: ActorAuthMethod; + actorOrgId?: string; + folders: Array<{ + name: string; + environment: string; + path: string; + description?: string | null; + }>; +}; + +export type TDeleteManyFoldersDTO = { + projectId: string; + actor: ActorType; + actorId: string; + actorAuthMethod: ActorAuthMethod; + actorOrgId?: string; + folders: Array<{ + environment: string; + path: string; + idOrName: string; + }>; +}; diff --git a/backend/src/services/secret-import/secret-import-service.ts b/backend/src/services/secret-import/secret-import-service.ts index 297c5d01f..403484fc2 100644 --- a/backend/src/services/secret-import/secret-import-service.ts +++ b/backend/src/services/secret-import/secret-import-service.ts @@ -2,7 +2,7 @@ import path from "node:path"; import { ForbiddenError, subject } from "@casl/ability"; -import { TableName } from "@app/db/schemas"; +import { ActionProjectType, TableName } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { hasSecretReadValueOrDescribePermission, @@ -87,7 +87,8 @@ export const secretImportServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); // check if user has permission to import into destination path @@ -204,7 +205,8 @@ export const secretImportServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -301,7 +303,8 @@ export const secretImportServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -375,7 +378,8 @@ export const secretImportServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); // check if user has permission to import into destination path @@ -451,7 +455,8 @@ export const secretImportServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Read, @@ -484,7 +489,8 @@ export const secretImportServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const filteredEnvironments = []; for (const environment of environments) { @@ -537,7 +543,8 @@ export const secretImportServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Read, @@ -586,7 +593,8 @@ export const secretImportServiceFactory = ({ actorId, projectId: folder.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -634,7 +642,8 @@ export const secretImportServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Read, @@ -669,7 +678,8 @@ export const secretImportServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Read, @@ -752,7 +762,8 @@ export const secretImportServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const filteredEnvironments = []; for (const environment of environments) { @@ -804,7 +815,8 @@ export const secretImportServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); if ( permission.cannot( diff --git a/backend/src/services/secret-sync/bitbucket/bitbucket-sync-constants.ts b/backend/src/services/secret-sync/bitbucket/bitbucket-sync-constants.ts new file mode 100644 index 000000000..121d3910d --- /dev/null +++ b/backend/src/services/secret-sync/bitbucket/bitbucket-sync-constants.ts @@ -0,0 +1,10 @@ +import { AppConnection } from "@app/services/app-connection/app-connection-enums"; +import { SecretSync } from "@app/services/secret-sync/secret-sync-enums"; +import { TSecretSyncListItem } from "@app/services/secret-sync/secret-sync-types"; + +export const BITBUCKET_SYNC_LIST_OPTION: TSecretSyncListItem = { + name: "Bitbucket", + destination: SecretSync.Bitbucket, + connection: AppConnection.Bitbucket, + canImportSecrets: false +}; diff --git a/backend/src/services/secret-sync/bitbucket/bitbucket-sync-fns.ts b/backend/src/services/secret-sync/bitbucket/bitbucket-sync-fns.ts new file mode 100644 index 000000000..93b285c79 --- /dev/null +++ b/backend/src/services/secret-sync/bitbucket/bitbucket-sync-fns.ts @@ -0,0 +1,222 @@ +import { request } from "@app/lib/config/request"; +import { createAuthHeader } from "@app/services/app-connection/bitbucket"; +import { IntegrationUrls } from "@app/services/integration-auth/integration-list"; +import { + TBitbucketListVariables, + TBitbucketSyncWithCredentials, + TBitbucketVariable, + TDeleteBitbucketVariable, + TPutBitbucketVariable +} from "@app/services/secret-sync/bitbucket/bitbucket-sync-types"; +import { SecretSyncError } from "@app/services/secret-sync/secret-sync-errors"; +import { matchesSchema } from "@app/services/secret-sync/secret-sync-fns"; +import { TSecretMap } from "@app/services/secret-sync/secret-sync-types"; + +import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps"; + +const buildVariablesUrl = (workspace: string, repository: string, environment?: string, uuid?: string): string => { + const baseUrl = `${IntegrationUrls.BITBUCKET_API_URL}/2.0/repositories/${encodeURIComponent(workspace)}/${encodeURIComponent(repository)}`; + + if (environment) { + return `${baseUrl}/deployments_config/environments/${environment}/variables/${uuid || ""}`; + } + + return `${baseUrl}/pipelines_config/variables/${uuid || ""}`; +}; + +const listVariables = async ({ + workspaceSlug, + repositorySlug, + environmentId, + authHeader +}: TBitbucketListVariables): Promise => { + const url = buildVariablesUrl(workspaceSlug, repositorySlug, environmentId); + + const { data } = await request.get<{ values: TBitbucketVariable[] }>(url, { + headers: { + Authorization: authHeader, + Accept: "application/json" + } + }); + + return data.values; +}; + +const upsertVariable = async ({ + workspaceSlug, + repositorySlug, + environmentId, + key, + value, + existingVariables, + authHeader +}: { + workspaceSlug: string; + repositorySlug: string; + environmentId?: string; + key: string; + value: string; + existingVariables: TBitbucketVariable[]; + authHeader: string; +}) => { + const existingVariable = existingVariables.find((variable) => variable.key === key); + const requestData = { key, value, secured: true }; + const headers = { + Authorization: authHeader, + "Content-Type": "application/json" + }; + + if (existingVariable) { + const url = buildVariablesUrl(workspaceSlug, repositorySlug, environmentId, existingVariable.uuid); + return request.put(url, requestData, { headers }); + } + + const url = buildVariablesUrl(workspaceSlug, repositorySlug, environmentId); + return request.post(url, requestData, { headers }); +}; + +const putVariables = async ({ + workspaceSlug, + repositorySlug, + environmentId, + secretMap, + authHeader +}: TPutBitbucketVariable & { secretMap: TSecretMap; authHeader: string }) => { + const existingVariables = await listVariables({ + workspaceSlug, + repositorySlug, + environmentId, + authHeader + }); + + const promises = Object.entries(secretMap).map(([key, { value }]) => + upsertVariable({ + workspaceSlug, + repositorySlug, + environmentId, + key, + value, + existingVariables, + authHeader + }) + ); + + return Promise.all(promises); +}; + +const deleteVariables = async ({ + workspaceSlug, + repositorySlug, + environmentId, + keys, + authHeader +}: TDeleteBitbucketVariable) => { + const existingVariables = await listVariables({ + workspaceSlug, + repositorySlug, + environmentId, + authHeader + }); + + const variablesToDelete = existingVariables.filter((variable) => keys.includes(variable.key)); + const promises = variablesToDelete.map((variable) => { + const url = buildVariablesUrl(workspaceSlug, repositorySlug, environmentId, variable.uuid); + return request.delete(url, { + headers: { Authorization: authHeader } + }); + }); + + return Promise.all(promises); +}; + +export const BitbucketSyncFns = { + syncSecrets: async (secretSync: TBitbucketSyncWithCredentials, secretMap: TSecretMap) => { + const { + connection, + environment, + destinationConfig: { workspaceSlug, repositorySlug, environmentId } + } = secretSync; + + const { email, apiToken } = connection.credentials; + const authHeader = createAuthHeader(email, apiToken); + + try { + await putVariables({ + workspaceSlug, + repositorySlug, + environmentId, + secretMap, + authHeader + }); + } catch (error) { + throw new SecretSyncError({ error }); + } + + if (secretSync.syncOptions.disableSecretDeletion) return; + + try { + const existingVariables = await listVariables({ + workspaceSlug, + repositorySlug, + environmentId, + authHeader + }); + + const keysToDelete = existingVariables + .map((variable) => variable.key) + .filter( + (secret) => + matchesSchema(secret, environment?.slug || "", secretSync.syncOptions.keySchema) && !(secret in secretMap) + ); + + if (keysToDelete.length > 0) { + await deleteVariables({ + workspaceSlug, + repositorySlug, + environmentId, + keys: keysToDelete, + authHeader + }); + } + } catch (error) { + throw new SecretSyncError({ error }); + } + }, + + removeSecrets: async (secretSync: TBitbucketSyncWithCredentials, secretMap: TSecretMap) => { + const { + connection, + destinationConfig: { workspaceSlug, repositorySlug, environmentId } + } = secretSync; + + const { email, apiToken } = connection.credentials; + const authHeader = createAuthHeader(email, apiToken); + + try { + const existingVariables = await listVariables({ + workspaceSlug, + repositorySlug, + environmentId, + authHeader + }); + + const keysToRemove = existingVariables.map((variable) => variable.key).filter((secret) => secret in secretMap); + + if (keysToRemove.length > 0) { + await deleteVariables({ + workspaceSlug, + repositorySlug, + environmentId, + keys: keysToRemove, + authHeader + }); + } + } catch (error) { + throw new SecretSyncError({ error }); + } + }, + + getSecrets: async (secretSync: TBitbucketSyncWithCredentials): Promise => { + throw new Error(`${SECRET_SYNC_NAME_MAP[secretSync.destination]} does not support importing secrets.`); + } +}; diff --git a/backend/src/services/secret-sync/bitbucket/bitbucket-sync-schemas.ts b/backend/src/services/secret-sync/bitbucket/bitbucket-sync-schemas.ts new file mode 100644 index 000000000..985d86e8d --- /dev/null +++ b/backend/src/services/secret-sync/bitbucket/bitbucket-sync-schemas.ts @@ -0,0 +1,45 @@ +import { z } from "zod"; + +import { SecretSyncs } from "@app/lib/api-docs"; +import { AppConnection } from "@app/services/app-connection/app-connection-enums"; +import { SecretSync } from "@app/services/secret-sync/secret-sync-enums"; +import { + BaseSecretSyncSchema, + GenericCreateSecretSyncFieldsSchema, + GenericUpdateSecretSyncFieldsSchema +} from "@app/services/secret-sync/secret-sync-schemas"; +import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; + +const BitbucketSyncDestinationConfigSchema = z.object({ + repositorySlug: z.string().describe(SecretSyncs.DESTINATION_CONFIG.BITBUCKET.repositorySlug), + environmentId: z.string().optional().describe(SecretSyncs.DESTINATION_CONFIG.BITBUCKET.environmentId), + workspaceSlug: z.string().describe(SecretSyncs.DESTINATION_CONFIG.BITBUCKET.workspaceSlug) +}); + +const BitbucketSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false }; + +export const BitbucketSyncSchema = BaseSecretSyncSchema(SecretSync.Bitbucket, BitbucketSyncOptionsConfig).extend({ + destination: z.literal(SecretSync.Bitbucket), + destinationConfig: BitbucketSyncDestinationConfigSchema +}); + +export const CreateBitbucketSyncSchema = GenericCreateSecretSyncFieldsSchema( + SecretSync.Bitbucket, + BitbucketSyncOptionsConfig +).extend({ + destinationConfig: BitbucketSyncDestinationConfigSchema +}); + +export const UpdateBitbucketSyncSchema = GenericUpdateSecretSyncFieldsSchema( + SecretSync.Bitbucket, + BitbucketSyncOptionsConfig +).extend({ + destinationConfig: BitbucketSyncDestinationConfigSchema.optional() +}); + +export const BitbucketSyncListItemSchema = z.object({ + name: z.literal("Bitbucket"), + connection: z.literal(AppConnection.Bitbucket), + destination: z.literal(SecretSync.Bitbucket), + canImportSecrets: z.literal(false) +}); diff --git a/backend/src/services/secret-sync/bitbucket/bitbucket-sync-types.ts b/backend/src/services/secret-sync/bitbucket/bitbucket-sync-types.ts new file mode 100644 index 000000000..a28e27487 --- /dev/null +++ b/backend/src/services/secret-sync/bitbucket/bitbucket-sync-types.ts @@ -0,0 +1,50 @@ +import { z } from "zod"; + +import { TBitbucketConnection } from "@app/services/app-connection/bitbucket"; + +import { BitbucketSyncListItemSchema, BitbucketSyncSchema, CreateBitbucketSyncSchema } from "./bitbucket-sync-schemas"; + +export type TBitbucketSync = z.infer; + +export type TBitbucketSyncInput = z.infer; + +export type TBitbucketSyncListItem = z.infer; + +export type TBitbucketSyncWithCredentials = TBitbucketSync & { + connection: TBitbucketConnection; +}; + +export type TBitbucketVariable = { + key: string; + value?: string; + // Secure variables values are not returned by the API neither are they shown in Bitbucket UI + secured: boolean; + uuid: string; + type: string; +}; + +export type TBitbucketListVariables = { + workspaceSlug: string; + repositorySlug: string; + environmentId?: string; + authHeader: string; +}; + +export type TPutBitbucketVariable = { + authHeader: string; + workspaceSlug: string; + repositorySlug: string; + environmentId?: string; +}; + +export type TDeleteBitbucketVariable = { + authHeader: string; + workspaceSlug: string; + repositorySlug: string; + environmentId?: string; + keys: string[]; +}; + +export type TBitbucketConnectionCredentials = { + authHeader: string; +}; diff --git a/backend/src/services/secret-sync/bitbucket/index.ts b/backend/src/services/secret-sync/bitbucket/index.ts new file mode 100644 index 000000000..d0f20bd45 --- /dev/null +++ b/backend/src/services/secret-sync/bitbucket/index.ts @@ -0,0 +1,4 @@ +export * from "./bitbucket-sync-constants"; +export * from "./bitbucket-sync-fns"; +export * from "./bitbucket-sync-schemas"; +export * from "./bitbucket-sync-types"; diff --git a/backend/src/services/secret-sync/render/render-sync-fns.ts b/backend/src/services/secret-sync/render/render-sync-fns.ts index 8a9039e2e..9140136a0 100644 --- a/backend/src/services/secret-sync/render/render-sync-fns.ts +++ b/backend/src/services/secret-sync/render/render-sync-fns.ts @@ -1,4 +1,6 @@ /* eslint-disable no-await-in-loop */ +import { isAxiosError } from "axios"; + import { request } from "@app/lib/config/request"; import { IntegrationUrls } from "@app/services/integration-auth/integration-list"; import { matchesSchema } from "@app/services/secret-sync/secret-sync-fns"; @@ -71,7 +73,7 @@ const putEnvironmentSecret = async (secretSync: TRenderSyncWithCredentials, secr ); }; -const deleteEnvironmentSecret = async (secretSync: TRenderSyncWithCredentials, secret: TRenderSecret) => { +const deleteEnvironmentSecret = async (secretSync: TRenderSyncWithCredentials, secret: Pick) => { const { destinationConfig, connection: { @@ -79,15 +81,24 @@ const deleteEnvironmentSecret = async (secretSync: TRenderSyncWithCredentials, s } } = secretSync; - await request.delete( - `${IntegrationUrls.RENDER_API_URL}/v1/services/${destinationConfig.serviceId}/env-vars/${secret.key}`, - { - headers: { - Authorization: `Bearer ${apiKey}`, - Accept: "application/json" + try { + await request.delete( + `${IntegrationUrls.RENDER_API_URL}/v1/services/${destinationConfig.serviceId}/env-vars/${secret.key}`, + { + headers: { + Authorization: `Bearer ${apiKey}`, + Accept: "application/json" + } } + ); + } catch (error) { + if (isAxiosError(error) && error.response?.status === 404) { + // If the secret does not exist, we can ignore this error + return; } - ); + + throw error; + } }; const sleep = async () => @@ -99,6 +110,11 @@ export const RenderSyncFns = { syncSecrets: async (secretSync: TRenderSyncWithCredentials, secretMap: TSecretMap) => { const renderSecrets = await getRenderEnvironmentSecrets(secretSync); for await (const key of Object.keys(secretMap)) { + // If value is empty skip it as render does not allow empty variables + if (secretMap[key].value === "") { + // eslint-disable-next-line no-continue + continue; + } await putEnvironmentSecret(secretSync, secretMap, key); await sleep(); } diff --git a/backend/src/services/secret-sync/secret-sync-enums.ts b/backend/src/services/secret-sync/secret-sync-enums.ts index 8d08e4d82..2c02e2ff4 100644 --- a/backend/src/services/secret-sync/secret-sync-enums.ts +++ b/backend/src/services/secret-sync/secret-sync-enums.ts @@ -25,7 +25,8 @@ export enum SecretSync { Supabase = "supabase", Zabbix = "zabbix", Railway = "railway", - Checkly = "checkly" + Checkly = "checkly", + Bitbucket = "bitbucket" } export enum SecretSyncInitialSyncBehavior { diff --git a/backend/src/services/secret-sync/secret-sync-fns.ts b/backend/src/services/secret-sync/secret-sync-fns.ts index 3daa9232f..827a41b7d 100644 --- a/backend/src/services/secret-sync/secret-sync-fns.ts +++ b/backend/src/services/secret-sync/secret-sync-fns.ts @@ -28,6 +28,7 @@ import { ONEPASS_SYNC_LIST_OPTION, OnePassSyncFns } from "./1password"; import { AZURE_APP_CONFIGURATION_SYNC_LIST_OPTION, azureAppConfigurationSyncFactory } from "./azure-app-configuration"; import { AZURE_DEVOPS_SYNC_LIST_OPTION, azureDevOpsSyncFactory } from "./azure-devops"; import { AZURE_KEY_VAULT_SYNC_LIST_OPTION, azureKeyVaultSyncFactory } from "./azure-key-vault"; +import { BITBUCKET_SYNC_LIST_OPTION, BitbucketSyncFns } from "./bitbucket"; import { CAMUNDA_SYNC_LIST_OPTION, camundaSyncFactory } from "./camunda"; import { CHECKLY_SYNC_LIST_OPTION } from "./checkly/checkly-sync-constants"; import { ChecklySyncFns } from "./checkly/checkly-sync-fns"; @@ -80,7 +81,8 @@ const SECRET_SYNC_LIST_OPTIONS: Record = { [SecretSync.Supabase]: SUPABASE_SYNC_LIST_OPTION, [SecretSync.Zabbix]: ZABBIX_SYNC_LIST_OPTION, [SecretSync.Railway]: RAILWAY_SYNC_LIST_OPTION, - [SecretSync.Checkly]: CHECKLY_SYNC_LIST_OPTION + [SecretSync.Checkly]: CHECKLY_SYNC_LIST_OPTION, + [SecretSync.Bitbucket]: BITBUCKET_SYNC_LIST_OPTION }; export const listSecretSyncOptions = () => { @@ -258,6 +260,8 @@ export const SecretSyncFns = { return ChecklySyncFns.syncSecrets(secretSync, schemaSecretMap); case SecretSync.Supabase: return SupabaseSyncFns.syncSecrets(secretSync, schemaSecretMap); + case SecretSync.Bitbucket: + return BitbucketSyncFns.syncSecrets(secretSync, schemaSecretMap); default: throw new Error( `Unhandled sync destination for sync secrets fns: ${(secretSync as TSecretSyncWithCredentials).destination}` @@ -365,6 +369,9 @@ export const SecretSyncFns = { case SecretSync.Supabase: secretMap = await SupabaseSyncFns.getSecrets(secretSync); break; + case SecretSync.Bitbucket: + secretMap = await BitbucketSyncFns.getSecrets(secretSync); + break; default: throw new Error( `Unhandled sync destination for get secrets fns: ${(secretSync as TSecretSyncWithCredentials).destination}` @@ -452,6 +459,8 @@ export const SecretSyncFns = { return ChecklySyncFns.removeSecrets(secretSync, schemaSecretMap); case SecretSync.Supabase: return SupabaseSyncFns.removeSecrets(secretSync, schemaSecretMap); + case SecretSync.Bitbucket: + return BitbucketSyncFns.removeSecrets(secretSync, schemaSecretMap); default: throw new Error( `Unhandled sync destination for remove secrets fns: ${(secretSync as TSecretSyncWithCredentials).destination}` diff --git a/backend/src/services/secret-sync/secret-sync-maps.ts b/backend/src/services/secret-sync/secret-sync-maps.ts index a8a017480..1de9838e3 100644 --- a/backend/src/services/secret-sync/secret-sync-maps.ts +++ b/backend/src/services/secret-sync/secret-sync-maps.ts @@ -28,7 +28,8 @@ export const SECRET_SYNC_NAME_MAP: Record = { [SecretSync.Supabase]: "Supabase", [SecretSync.Zabbix]: "Zabbix", [SecretSync.Railway]: "Railway", - [SecretSync.Checkly]: "Checkly" + [SecretSync.Checkly]: "Checkly", + [SecretSync.Bitbucket]: "Bitbucket" }; export const SECRET_SYNC_CONNECTION_MAP: Record = { @@ -58,7 +59,8 @@ export const SECRET_SYNC_CONNECTION_MAP: Record = { [SecretSync.Supabase]: AppConnection.Supabase, [SecretSync.Zabbix]: AppConnection.Zabbix, [SecretSync.Railway]: AppConnection.Railway, - [SecretSync.Checkly]: AppConnection.Checkly + [SecretSync.Checkly]: AppConnection.Checkly, + [SecretSync.Bitbucket]: AppConnection.Bitbucket }; export const SECRET_SYNC_PLAN_MAP: Record = { @@ -88,5 +90,6 @@ export const SECRET_SYNC_PLAN_MAP: Record = { [SecretSync.Supabase]: SecretSyncPlanType.Regular, [SecretSync.Zabbix]: SecretSyncPlanType.Regular, [SecretSync.Railway]: SecretSyncPlanType.Regular, - [SecretSync.Checkly]: SecretSyncPlanType.Regular + [SecretSync.Checkly]: SecretSyncPlanType.Regular, + [SecretSync.Bitbucket]: SecretSyncPlanType.Regular }; diff --git a/backend/src/services/secret-sync/secret-sync-service.ts b/backend/src/services/secret-sync/secret-sync-service.ts index bd52c0b77..3fdb7fea6 100644 --- a/backend/src/services/secret-sync/secret-sync-service.ts +++ b/backend/src/services/secret-sync/secret-sync-service.ts @@ -1,5 +1,6 @@ import { ForbiddenError, subject } from "@casl/ability"; +import { ActionProjectType } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { throwIfMissingSecretReadValueOrDescribePermission } from "@app/ee/services/permission/permission-fns"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; @@ -74,7 +75,7 @@ export const secretSyncServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretManager, projectId }); @@ -110,7 +111,7 @@ export const secretSyncServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretManager, projectId }); @@ -153,7 +154,7 @@ export const secretSyncServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretManager, projectId: secretSync.projectId }); @@ -195,7 +196,7 @@ export const secretSyncServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretManager, projectId: secretSync.projectId }); @@ -233,7 +234,7 @@ export const secretSyncServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretManager, projectId }); @@ -313,7 +314,7 @@ export const secretSyncServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretManager, projectId: secretSync.projectId }); @@ -429,7 +430,7 @@ export const secretSyncServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretManager, projectId: secretSync.projectId }); @@ -506,7 +507,7 @@ export const secretSyncServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretManager, projectId: secretSync.projectId }); @@ -578,7 +579,7 @@ export const secretSyncServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretManager, projectId: secretSync.projectId }); @@ -644,7 +645,7 @@ export const secretSyncServiceFactory = ({ actorId: actor.id, actorAuthMethod: actor.authMethod, actorOrgId: actor.orgId, - + actionProjectType: ActionProjectType.SecretManager, projectId: secretSync.projectId }); diff --git a/backend/src/services/secret-sync/secret-sync-types.ts b/backend/src/services/secret-sync/secret-sync-types.ts index 2c8753d66..007c79bf7 100644 --- a/backend/src/services/secret-sync/secret-sync-types.ts +++ b/backend/src/services/secret-sync/secret-sync-types.ts @@ -72,6 +72,12 @@ import { TAzureKeyVaultSyncListItem, TAzureKeyVaultSyncWithCredentials } from "./azure-key-vault"; +import { + TBitbucketSync, + TBitbucketSyncInput, + TBitbucketSyncListItem, + TBitbucketSyncWithCredentials +} from "./bitbucket/bitbucket-sync-types"; import { TChecklySync, TChecklySyncInput, @@ -166,7 +172,8 @@ export type TSecretSync = | TZabbixSync | TRailwaySync | TChecklySync - | TSupabaseSync; + | TSupabaseSync + | TBitbucketSync; export type TSecretSyncWithCredentials = | TAwsParameterStoreSyncWithCredentials @@ -195,7 +202,8 @@ export type TSecretSyncWithCredentials = | TZabbixSyncWithCredentials | TRailwaySyncWithCredentials | TChecklySyncWithCredentials - | TSupabaseSyncWithCredentials; + | TSupabaseSyncWithCredentials + | TBitbucketSyncWithCredentials; export type TSecretSyncInput = | TAwsParameterStoreSyncInput @@ -224,7 +232,8 @@ export type TSecretSyncInput = | TZabbixSyncInput | TRailwaySyncInput | TChecklySyncInput - | TSupabaseSyncInput; + | TSupabaseSyncInput + | TBitbucketSyncInput; export type TSecretSyncListItem = | TAwsParameterStoreSyncListItem @@ -253,7 +262,8 @@ export type TSecretSyncListItem = | TZabbixSyncListItem | TRailwaySyncListItem | TChecklySyncListItem - | TSupabaseSyncListItem; + | TSupabaseSyncListItem + | TBitbucketSyncListItem; export type TSyncOptionsConfig = { canImportSecrets: boolean; diff --git a/backend/src/services/secret-tag/secret-tag-service.ts b/backend/src/services/secret-tag/secret-tag-service.ts index a4be06b4f..8a08c44dd 100644 --- a/backend/src/services/secret-tag/secret-tag-service.ts +++ b/backend/src/services/secret-tag/secret-tag-service.ts @@ -1,5 +1,6 @@ import { ForbiddenError } from "@casl/ability"; +import { ActionProjectType } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; @@ -28,7 +29,8 @@ export const secretTagServiceFactory = ({ secretTagDAL, permissionService }: TSe actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Tags); @@ -59,7 +61,8 @@ export const secretTagServiceFactory = ({ secretTagDAL, permissionService }: TSe actorId, projectId: tag.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Tags); @@ -76,7 +79,8 @@ export const secretTagServiceFactory = ({ secretTagDAL, permissionService }: TSe actorId, projectId: tag.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Tags); @@ -93,7 +97,8 @@ export const secretTagServiceFactory = ({ secretTagDAL, permissionService }: TSe actorId, projectId: tag.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Tags); @@ -109,7 +114,8 @@ export const secretTagServiceFactory = ({ secretTagDAL, permissionService }: TSe actorId, projectId: tag.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Tags); @@ -122,7 +128,8 @@ export const secretTagServiceFactory = ({ secretTagDAL, permissionService }: TSe actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Tags); diff --git a/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts b/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts index b0d114bd8..7aee91273 100644 --- a/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts +++ b/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts @@ -67,6 +67,7 @@ export const getAllSecretReferences = (maybeSecretReference: string) => { export const fnSecretBulkInsert = async ({ // TODO: Pick types here folderId, + commitChanges, orgId, inputSecrets, secretDAL, @@ -134,28 +135,32 @@ export const fnSecretBulkInsert = async ({ tx ); - const commitChanges = secretVersions + const changes = secretVersions .filter(({ type }) => type === SecretType.Shared) .map((sv) => ({ type: CommitType.ADD, secretVersionId: sv.id })); - if (commitChanges.length > 0) { - await folderCommitService.createCommit( - { - actor: { - type: actorType || ActorType.PLATFORM, - metadata: { - id: actor?.actorId - } + if (changes.length > 0) { + if (commitChanges) { + commitChanges.push(...changes); + } else { + await folderCommitService.createCommit( + { + actor: { + type: actorType || ActorType.PLATFORM, + metadata: { + id: actor?.actorId + } + }, + message: "Secret Created", + folderId, + changes }, - message: "Secret Created", - folderId, - changes: commitChanges - }, - tx - ); + tx + ); + } } await secretDAL.upsertSecretReferences( @@ -209,6 +214,7 @@ export const fnSecretBulkUpdate = async ({ tx, inputSecrets, folderId, + commitChanges, orgId, secretDAL, secretVersionDAL, @@ -223,7 +229,10 @@ export const fnSecretBulkUpdate = async ({ const actorType = actor?.type || ActorType.PLATFORM; const sanitizedInputSecrets = inputSecrets.map( - ({ filter, data: { skipMultilineEncoding, type, key, encryptedValue, userId, encryptedComment, metadata } }) => ({ + ({ + filter, + data: { skipMultilineEncoding, type, key, encryptedValue, userId, encryptedComment, metadata, secretMetadata } + }) => ({ filter: { ...filter, folderId }, data: { skipMultilineEncoding, @@ -231,7 +240,7 @@ export const fnSecretBulkUpdate = async ({ key, userId, encryptedComment, - metadata, + metadata: JSON.stringify(metadata || secretMetadata || []), encryptedValue } }) @@ -340,28 +349,32 @@ export const fnSecretBulkUpdate = async ({ { tx } ); - const commitChanges = secretVersions + const changes = secretVersions .filter(({ type }) => type === SecretType.Shared) .map((sv) => ({ type: CommitType.ADD, isUpdate: true, secretVersionId: sv.id })); - if (commitChanges.length > 0) { - await folderCommitService.createCommit( - { - actor: { - type: actorType || ActorType.PLATFORM, - metadata: { - id: actor?.actorId - } + if (changes.length > 0) { + if (commitChanges) { + commitChanges.push(...changes); + } else { + await folderCommitService.createCommit( + { + actor: { + type: actorType || ActorType.PLATFORM, + metadata: { + id: actor?.actorId + } + }, + message: "Secret Updated", + folderId, + changes }, - message: "Secret Updated", - folderId, - changes: commitChanges - }, - tx - ); + tx + ); + } } return secretsWithTags.map((secret) => ({ ...secret, _id: secret.id })); @@ -377,7 +390,8 @@ export const fnSecretBulkDelete = async ({ secretQueueService, folderCommitService, secretVersionDAL, - projectId + projectId, + commitChanges }: TFnSecretBulkDelete) => { const deletedSecrets = await secretDAL.deleteMany( inputSecrets.map(({ type, secretKey }) => ({ @@ -406,27 +420,31 @@ export const fnSecretBulkDelete = async ({ tx ); - const commitChanges = deletedSecrets + const changes = deletedSecrets .filter(({ type }) => type === SecretType.Shared) .map(({ id }) => ({ type: CommitType.DELETE, secretVersionId: secretVersions[id].id })); - if (commitChanges.length > 0) { - await folderCommitService.createCommit( - { - actor: { - type: actorType || ActorType.PLATFORM, - metadata: { - id: actorId - } + if (changes.length > 0) { + if (commitChanges) { + commitChanges.push(...changes); + } else { + await folderCommitService.createCommit( + { + actor: { + type: actorType || ActorType.PLATFORM, + metadata: { + id: actorId + } + }, + message: "Secret Deleted", + folderId, + changes }, - message: "Secret Deleted", - folderId, - changes: commitChanges - }, - tx - ); + tx + ); + } } return deletedSecrets; diff --git a/backend/src/services/secret-v2-bridge/secret-v2-bridge-service.ts b/backend/src/services/secret-v2-bridge/secret-v2-bridge-service.ts index b77294cae..2fa0ffe9b 100644 --- a/backend/src/services/secret-v2-bridge/secret-v2-bridge-service.ts +++ b/backend/src/services/secret-v2-bridge/secret-v2-bridge-service.ts @@ -2,7 +2,14 @@ import { ForbiddenError, MongoAbility, subject } from "@casl/ability"; import { Knex } from "knex"; import { z } from "zod"; -import { ProjectMembershipRole, SecretsV2Schema, SecretType, TableName, TSecretsV2 } from "@app/db/schemas"; +import { + ActionProjectType, + ProjectMembershipRole, + SecretsV2Schema, + SecretType, + TableName, + TSecretsV2 +} from "@app/db/schemas"; import { hasSecretReadValueOrDescribePermission, throwIfMissingSecretReadValueOrDescribePermission @@ -28,7 +35,7 @@ import { logger } from "@app/lib/logger"; import { alphaNumericNanoId } from "@app/lib/nanoid"; import { ActorType } from "../auth/auth-type"; -import { TFolderCommitServiceFactory } from "../folder-commit/folder-commit-service"; +import { TCommitResourceChangeDTO, TFolderCommitServiceFactory } from "../folder-commit/folder-commit-service"; import { TKmsServiceFactory } from "../kms/kms-service"; import { KmsDataKey } from "../kms/kms-types"; import { TProjectEnvDALFactory } from "../project-env/project-env-dal"; @@ -239,7 +246,8 @@ export const secretV2BridgeServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath); @@ -394,7 +402,8 @@ export const secretV2BridgeServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); if (inputSecret.newSecretName === "") { @@ -620,7 +629,8 @@ export const secretV2BridgeServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath); @@ -756,7 +766,8 @@ export const secretV2BridgeServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.DescribeSecret); } @@ -801,7 +812,8 @@ export const secretV2BridgeServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.DescribeSecret); @@ -900,7 +912,8 @@ export const secretV2BridgeServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); if (!isInternal) { throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.DescribeSecret); @@ -953,7 +966,8 @@ export const secretV2BridgeServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.DescribeSecret); @@ -1251,7 +1265,8 @@ export const secretV2BridgeServiceFactory = ({ actorId, projectId: secret.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, { @@ -1314,7 +1329,8 @@ export const secretV2BridgeServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const folder = await folderDAL.findBySecretPath(projectId, environment, path); @@ -1519,14 +1535,17 @@ export const secretV2BridgeServiceFactory = ({ actorOrgId, environment, projectId, - secrets: inputSecrets - }: TCreateManySecretDTO) => { + secrets: inputSecrets, + tx: providedTx, + commitChanges + }: TCreateManySecretDTO & { tx?: Knex; commitChanges?: TCommitResourceChangeDTO[] }) => { const { permission } = await permissionService.getProjectPermission({ actor, actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath); @@ -1603,8 +1622,8 @@ export const secretV2BridgeServiceFactory = ({ const { encryptor: secretManagerEncryptor, decryptor: secretManagerDecryptor } = await kmsService.createCipherPairWithDataKey({ type: KmsDataKey.SecretManager, projectId }); - const newSecrets = await secretDAL.transaction(async (tx) => - fnSecretBulkInsert({ + const executeBulkInsert = async (tx: Knex) => { + return fnSecretBulkInsert({ inputSecrets: inputSecrets.map((el) => { const references = secretReferencesGroupByInputSecretKey[el.secretKey]?.nestedReferences; @@ -1626,6 +1645,7 @@ export const secretV2BridgeServiceFactory = ({ }; }), folderId, + commitChanges, orgId: actorOrgId, secretDAL, resourceMetadataDAL, @@ -1638,8 +1658,13 @@ export const secretV2BridgeServiceFactory = ({ actorId }, tx - }) - ); + }); + }; + + const newSecrets = providedTx + ? await executeBulkInsert(providedTx) + : await secretDAL.transaction(executeBulkInsert); + await secretDAL.invalidateSecretCacheByProjectId(projectId); await snapshotService.performSnapshot(folderId); await secretQueueService.syncSecrets({ @@ -1686,14 +1711,17 @@ export const secretV2BridgeServiceFactory = ({ projectId, secretPath: defaultSecretPath = "/", secrets: inputSecrets, - mode: updateMode - }: TUpdateManySecretDTO) => { + mode: updateMode, + tx: providedTx, + commitChanges + }: TUpdateManySecretDTO & { tx?: Knex; commitChanges?: TCommitResourceChangeDTO[] }) => { const { permission } = await permissionService.getProjectPermission({ actor, actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const secretsToUpdateGroupByPath = groupBy(inputSecrets, (el) => el.secretPath || defaultSecretPath); @@ -1716,18 +1744,20 @@ export const secretV2BridgeServiceFactory = ({ const { encryptor: secretManagerEncryptor, decryptor: secretManagerDecryptor } = await kmsService.createCipherPairWithDataKey({ type: KmsDataKey.SecretManager, projectId }); - const updatedSecrets: Array< - TSecretsV2 & { - secretPath: string; - tags: { - id: string; - slug: string; - color?: string | null; - name: string; - }[]; - } - > = []; - await secretDAL.transaction(async (tx) => { + // Function to execute the bulk update operation + const executeBulkUpdate = async (tx: Knex) => { + const updatedSecrets: Array< + TSecretsV2 & { + secretPath: string; + tags: { + id: string; + slug: string; + color?: string | null; + name: string; + }[]; + } + > = []; + for await (const folder of folders) { if (!folder) throw new NotFoundError({ message: "Folder not found" }); @@ -1846,7 +1876,7 @@ export const secretV2BridgeServiceFactory = ({ { operator: "eq", field: `${TableName.SecretV2}.key` as "key", - value: el.secretKey + value: el.newSecretName as string }, { operator: "eq", @@ -1900,6 +1930,7 @@ export const secretV2BridgeServiceFactory = ({ orgId: actorOrgId, folderCommitService, tx, + commitChanges, inputSecrets: secretsToUpdate.map((el) => { const originalSecret = secretsToUpdateInDBGroupedByKey[el.secretKey][0]; const encryptedValue = @@ -1977,7 +2008,13 @@ export const secretV2BridgeServiceFactory = ({ updatedSecrets.push(...bulkInsertedSecrets.map((el) => ({ ...el, secretPath: folder.path }))); } } - }); + + return updatedSecrets; + }; + + const updatedSecrets = providedTx + ? await executeBulkUpdate(providedTx) + : await secretDAL.transaction(executeBulkUpdate); await secretDAL.invalidateSecretCacheByProjectId(projectId); await Promise.allSettled(folders.map((el) => (el?.id ? snapshotService.performSnapshot(el.id) : undefined))); @@ -2034,14 +2071,17 @@ export const secretV2BridgeServiceFactory = ({ actor, actorId, actorAuthMethod, - actorOrgId - }: TDeleteManySecretDTO) => { + actorOrgId, + tx: providedTx, + commitChanges + }: TDeleteManySecretDTO & { tx?: Knex; commitChanges?: TCommitResourceChangeDTO[] }) => { const { permission } = await permissionService.getProjectPermission({ actor, actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath); @@ -2094,24 +2134,29 @@ export const secretV2BridgeServiceFactory = ({ ); }); + const executeBulkDelete = async (tx: Knex) => { + return fnSecretBulkDelete({ + secretDAL, + secretQueueService, + folderCommitService, + secretVersionDAL, + inputSecrets: inputSecrets.map(({ type, secretKey }) => ({ + secretKey, + type: type || SecretType.Shared + })), + projectId, + folderId, + actorId, + actorType: actor, + commitChanges, + tx + }); + }; + try { - const secretsDeleted = await secretDAL.transaction(async (tx) => - fnSecretBulkDelete({ - secretDAL, - secretQueueService, - folderCommitService, - secretVersionDAL, - inputSecrets: inputSecrets.map(({ type, secretKey }) => ({ - secretKey, - type: type || SecretType.Shared - })), - projectId, - folderId, - actorId, - actorType: actor, - tx - }) - ); + const secretsDeleted = providedTx + ? await executeBulkDelete(providedTx) + : await secretDAL.transaction(executeBulkDelete); await secretDAL.invalidateSecretCacheByProjectId(projectId); await snapshotService.performSnapshot(folderId); @@ -2197,7 +2242,8 @@ export const secretV2BridgeServiceFactory = ({ actorId, projectId: folder.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const canRead = @@ -2262,7 +2308,8 @@ export const secretV2BridgeServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); if (!hasRole(ProjectMembershipRole.Admin)) @@ -2309,7 +2356,8 @@ export const secretV2BridgeServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const sourceFolder = await folderDAL.findBySecretPath(projectId, sourceEnvironment, sourceSecretPath); @@ -2693,7 +2741,8 @@ export const secretV2BridgeServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.DescribeSecret, { @@ -2786,7 +2835,8 @@ export const secretV2BridgeServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.DescribeSecret, { environment, @@ -2910,7 +2960,8 @@ export const secretV2BridgeServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const canRead = diff --git a/backend/src/services/secret-v2-bridge/secret-v2-bridge-types.ts b/backend/src/services/secret-v2-bridge/secret-v2-bridge-types.ts index 4027f784c..49d0eaf37 100644 --- a/backend/src/services/secret-v2-bridge/secret-v2-bridge-types.ts +++ b/backend/src/services/secret-v2-bridge/secret-v2-bridge-types.ts @@ -8,7 +8,7 @@ import { SecretsOrderBy } from "@app/services/secret/secret-types"; import { TSecretFolderDALFactory } from "@app/services/secret-folder/secret-folder-dal"; import { TSecretTagDALFactory } from "@app/services/secret-tag/secret-tag-dal"; -import { TFolderCommitServiceFactory } from "../folder-commit/folder-commit-service"; +import { TCommitResourceChangeDTO, TFolderCommitServiceFactory } from "../folder-commit/folder-commit-service"; import { TResourceMetadataDALFactory } from "../resource-metadata/resource-metadata-dal"; import { ResourceMetadataDTO } from "../resource-metadata/resource-metadata-schema"; import { TSecretV2BridgeDALFactory } from "./secret-v2-bridge-dal"; @@ -167,6 +167,7 @@ export type TFnSecretBulkInsert = { folderId: string; orgId: string; tx?: Knex; + commitChanges?: TCommitResourceChangeDTO[]; inputSecrets: Array< Omit & { tagIds?: string[]; @@ -214,6 +215,7 @@ export type TFnSecretBulkUpdate = { actorId?: string; }; tx?: Knex; + commitChanges?: TCommitResourceChangeDTO[]; }; export type TFnSecretBulkDelete = { @@ -223,6 +225,7 @@ export type TFnSecretBulkDelete = { actorId: string; actorType?: string; tx?: Knex; + commitChanges?: TCommitResourceChangeDTO[]; secretDAL: Pick; secretQueueService: { removeSecretReminder: (data: TRemoveSecretReminderDTO, tx?: Knex) => Promise; diff --git a/backend/src/services/secret/secret-fns.ts b/backend/src/services/secret/secret-fns.ts index 1442607cb..3b97f5891 100644 --- a/backend/src/services/secret/secret-fns.ts +++ b/backend/src/services/secret/secret-fns.ts @@ -3,6 +3,7 @@ import path from "path"; import RE2 from "re2"; import { + ActionProjectType, SecretEncryptionAlgo, SecretKeyEncoding, SecretType, @@ -180,7 +181,8 @@ export const recursivelyGetSecretPaths = ({ actorId: auth.actorId, projectId, actorAuthMethod: auth.actorAuthMethod, - actorOrgId: auth.actorOrgId + actorOrgId: auth.actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); // Filter out paths that the user does not have permission to access, and paths that are not in the current path diff --git a/backend/src/services/secret/secret-service.ts b/backend/src/services/secret/secret-service.ts index a7d3b2aea..7df668cb4 100644 --- a/backend/src/services/secret/secret-service.ts +++ b/backend/src/services/secret/secret-service.ts @@ -3,6 +3,7 @@ import { ForbiddenError, subject } from "@casl/ability"; import { + ActionProjectType, ProjectMembershipRole, ProjectUpgradeStatus, ProjectVersion, @@ -215,7 +216,8 @@ export const secretServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -332,7 +334,8 @@ export const secretServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -492,7 +495,8 @@ export const secretServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -608,7 +612,8 @@ export const secretServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); let paths: { folderId: string; path: string }[] = []; @@ -713,7 +718,8 @@ export const secretServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, { environment, @@ -818,7 +824,8 @@ export const secretServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionSecretActions.Create, @@ -904,7 +911,8 @@ export const secretServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -1026,7 +1034,8 @@ export const secretServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionSecretActions.Delete, @@ -2586,7 +2595,8 @@ export const secretServiceFactory = ({ actorId, projectId: folder.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback); const secretVersions = await secretVersionDAL.findBySecretId(secretId, { @@ -2678,7 +2688,8 @@ export const secretServiceFactory = ({ actorId, projectId: project.id, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -2783,7 +2794,8 @@ export const secretServiceFactory = ({ actorId, projectId: project.id, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan( @@ -2889,7 +2901,8 @@ export const secretServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); if (!hasRole(ProjectMembershipRole.Admin)) @@ -2974,7 +2987,8 @@ export const secretServiceFactory = ({ actorId, projectId: project.id, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); const { botKey } = await projectBotService.getBotKey(project.id); @@ -3381,7 +3395,8 @@ export const secretServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); if (!hasRole(ProjectMembershipRole.Admin)) @@ -3409,7 +3424,8 @@ export const secretServiceFactory = ({ actorId: actor.id, projectId: params.projectId, actorAuthMethod: actor.authMethod, - actorOrgId: actor.orgId + actorOrgId: actor.orgId, + actionProjectType: ActionProjectType.SecretManager }); const secrets = secretV2BridgeService.getSecretsByFolderMappings({ ...params, userId: actor.id }, permission); diff --git a/backend/src/services/secret/secret-types.ts b/backend/src/services/secret/secret-types.ts index 8af15818e..67766cb00 100644 --- a/backend/src/services/secret/secret-types.ts +++ b/backend/src/services/secret/secret-types.ts @@ -547,3 +547,33 @@ export enum SecretProtectionType { } export type TStartSecretsV2MigrationDTO = TProjectPermission; + +export type TProcessNewCommitRawDTO = { + secrets: { + create?: { + secretKey: string; + secretValue: string; + secretComment?: string; + skipMultilineEncoding?: boolean; + tagIds?: string[]; + secretMetadata?: ResourceMetadataDTO; + metadata?: { source?: string }; + }[]; + update?: { + secretKey: string; + newSecretName?: string; + secretValue?: string; + secretComment?: string; + skipMultilineEncoding?: boolean; + tagIds?: string[]; + secretMetadata?: ResourceMetadataDTO; + metadata?: { source?: string }; + }[]; + delete?: { secretKey: string }[]; + }; + folders: { + create?: { folderName: string; description?: string }[]; + update?: { folderName: string; description?: string | null; id: string }[]; + delete?: { folderName: string; id: string }[]; + }; +}; diff --git a/backend/src/services/service-token/service-token-service.ts b/backend/src/services/service-token/service-token-service.ts index 07362ff65..6d61cf898 100644 --- a/backend/src/services/service-token/service-token-service.ts +++ b/backend/src/services/service-token/service-token-service.ts @@ -1,5 +1,6 @@ import { ForbiddenError, subject } from "@casl/ability"; +import { ActionProjectType } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, @@ -65,7 +66,8 @@ export const serviceTokenServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.ServiceTokens); @@ -120,7 +122,8 @@ export const serviceTokenServiceFactory = ({ actorId, projectId: serviceToken.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.ServiceTokens); @@ -154,7 +157,8 @@ export const serviceTokenServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.SecretManager }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.ServiceTokens); diff --git a/backend/src/services/slack/slack-fns.ts b/backend/src/services/slack/slack-fns.ts index bee414179..a111d5372 100644 --- a/backend/src/services/slack/slack-fns.ts +++ b/backend/src/services/slack/slack-fns.ts @@ -50,7 +50,7 @@ const buildSlackPayload = (notification: TNotification) => { *Secret path*: ${payload.secretPath || "/"} *Secret Key${payload.secretKeys.length > 1 ? "s" : ""}*: ${payload.secretKeys.join(", ")} -View the complete details <${appCfg.SITE_URL}/projects/${payload.projectId}/secret-manager/approval?requestId=${ +View the complete details <${appCfg.SITE_URL}/projects/secret-management/${payload.projectId}/approval?requestId=${ payload.requestId }|here>.`; diff --git a/backend/src/services/webhook/webhook-service.ts b/backend/src/services/webhook/webhook-service.ts index ba3f2170a..eb58ee5bd 100644 --- a/backend/src/services/webhook/webhook-service.ts +++ b/backend/src/services/webhook/webhook-service.ts @@ -1,6 +1,6 @@ import { ForbiddenError } from "@casl/ability"; -import { TWebhooksInsert } from "@app/db/schemas"; +import { ActionProjectType, TWebhooksInsert } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { NotFoundError } from "@app/lib/errors"; @@ -54,7 +54,8 @@ export const webhookServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Webhooks); const env = await projectEnvDAL.findOne({ projectId, slug: environment }); @@ -92,7 +93,8 @@ export const webhookServiceFactory = ({ actorId, projectId: webhook.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Webhooks); @@ -109,7 +111,8 @@ export const webhookServiceFactory = ({ actorId, projectId: webhook.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Webhooks); @@ -126,7 +129,8 @@ export const webhookServiceFactory = ({ actorId, projectId: webhook.projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); const project = await projectDAL.findById(webhook.projectId); @@ -177,7 +181,8 @@ export const webhookServiceFactory = ({ actorId, projectId, actorAuthMethod, - actorOrgId + actorOrgId, + actionProjectType: ActionProjectType.Any }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Webhooks); diff --git a/docs/api-reference/endpoints/app-connections/okta/available.mdx b/docs/api-reference/endpoints/app-connections/okta/available.mdx new file mode 100644 index 000000000..169ddb51b --- /dev/null +++ b/docs/api-reference/endpoints/app-connections/okta/available.mdx @@ -0,0 +1,4 @@ +--- +title: "Available" +openapi: "GET /api/v1/app-connections/okta/available" +--- diff --git a/docs/api-reference/endpoints/app-connections/okta/create.mdx b/docs/api-reference/endpoints/app-connections/okta/create.mdx new file mode 100644 index 000000000..732f83fa8 --- /dev/null +++ b/docs/api-reference/endpoints/app-connections/okta/create.mdx @@ -0,0 +1,8 @@ +--- +title: "Create" +openapi: "POST /api/v1/app-connections/okta" +--- + + + Check out the configuration docs for [Okta Connections](/integrations/app-connections/okta) to learn how to obtain the required credentials. + diff --git a/docs/api-reference/endpoints/app-connections/okta/delete.mdx b/docs/api-reference/endpoints/app-connections/okta/delete.mdx new file mode 100644 index 000000000..09abf8549 --- /dev/null +++ b/docs/api-reference/endpoints/app-connections/okta/delete.mdx @@ -0,0 +1,4 @@ +--- +title: "Delete" +openapi: "DELETE /api/v1/app-connections/okta/{connectionId}" +--- diff --git a/docs/api-reference/endpoints/app-connections/okta/get-by-id.mdx b/docs/api-reference/endpoints/app-connections/okta/get-by-id.mdx new file mode 100644 index 000000000..789f7b87d --- /dev/null +++ b/docs/api-reference/endpoints/app-connections/okta/get-by-id.mdx @@ -0,0 +1,4 @@ +--- +title: "Get by ID" +openapi: "GET /api/v1/app-connections/okta/{connectionId}" +--- diff --git a/docs/api-reference/endpoints/app-connections/okta/get-by-name.mdx b/docs/api-reference/endpoints/app-connections/okta/get-by-name.mdx new file mode 100644 index 000000000..763d42d72 --- /dev/null +++ b/docs/api-reference/endpoints/app-connections/okta/get-by-name.mdx @@ -0,0 +1,4 @@ +--- +title: "Get by Name" +openapi: "GET /api/v1/app-connections/okta/connection-name/{connectionName}" +--- diff --git a/docs/api-reference/endpoints/app-connections/okta/list.mdx b/docs/api-reference/endpoints/app-connections/okta/list.mdx new file mode 100644 index 000000000..81ac560f2 --- /dev/null +++ b/docs/api-reference/endpoints/app-connections/okta/list.mdx @@ -0,0 +1,4 @@ +--- +title: "List" +openapi: "GET /api/v1/app-connections/okta" +--- diff --git a/docs/api-reference/endpoints/app-connections/okta/update.mdx b/docs/api-reference/endpoints/app-connections/okta/update.mdx new file mode 100644 index 000000000..b063eeade --- /dev/null +++ b/docs/api-reference/endpoints/app-connections/okta/update.mdx @@ -0,0 +1,8 @@ +--- +title: "Update" +openapi: "PATCH /api/v1/app-connections/okta/{connectionId}" +--- + + + Check out the configuration docs for [Okta Connections](/integrations/app-connections/okta) to learn how to obtain the required credentials. + diff --git a/docs/api-reference/endpoints/secret-rotations/okta-client-secret/create.mdx b/docs/api-reference/endpoints/secret-rotations/okta-client-secret/create.mdx new file mode 100644 index 000000000..a92c1bc10 --- /dev/null +++ b/docs/api-reference/endpoints/secret-rotations/okta-client-secret/create.mdx @@ -0,0 +1,8 @@ +--- +title: "Create" +openapi: "POST /api/v2/secret-rotations/okta-client-secret" +--- + + + Check out the configuration docs for [Okta Client Secret Rotations](/documentation/platform/secret-rotation/okta-client-secret) to learn how to obtain the required parameters. + diff --git a/docs/api-reference/endpoints/secret-rotations/okta-client-secret/delete.mdx b/docs/api-reference/endpoints/secret-rotations/okta-client-secret/delete.mdx new file mode 100644 index 000000000..598eb1559 --- /dev/null +++ b/docs/api-reference/endpoints/secret-rotations/okta-client-secret/delete.mdx @@ -0,0 +1,4 @@ +--- +title: "Delete" +openapi: "DELETE /api/v2/secret-rotations/okta-client-secret/{rotationId}" +--- diff --git a/docs/api-reference/endpoints/secret-rotations/okta-client-secret/get-by-id.mdx b/docs/api-reference/endpoints/secret-rotations/okta-client-secret/get-by-id.mdx new file mode 100644 index 000000000..b2c9c281e --- /dev/null +++ b/docs/api-reference/endpoints/secret-rotations/okta-client-secret/get-by-id.mdx @@ -0,0 +1,4 @@ +--- +title: "Get by ID" +openapi: "GET /api/v2/secret-rotations/okta-client-secret/{rotationId}" +--- diff --git a/docs/api-reference/endpoints/secret-rotations/okta-client-secret/get-by-name.mdx b/docs/api-reference/endpoints/secret-rotations/okta-client-secret/get-by-name.mdx new file mode 100644 index 000000000..0eb400b7d --- /dev/null +++ b/docs/api-reference/endpoints/secret-rotations/okta-client-secret/get-by-name.mdx @@ -0,0 +1,4 @@ +--- +title: "Get by Name" +openapi: "GET /api/v2/secret-rotations/okta-client-secret/rotation-name/{rotationName}" +--- diff --git a/docs/api-reference/endpoints/secret-rotations/okta-client-secret/get-generated-credentials-by-id.mdx b/docs/api-reference/endpoints/secret-rotations/okta-client-secret/get-generated-credentials-by-id.mdx new file mode 100644 index 000000000..a74c52d92 --- /dev/null +++ b/docs/api-reference/endpoints/secret-rotations/okta-client-secret/get-generated-credentials-by-id.mdx @@ -0,0 +1,4 @@ +--- +title: "Get Credentials by ID" +openapi: "GET /api/v2/secret-rotations/okta-client-secret/{rotationId}/generated-credentials" +--- diff --git a/docs/api-reference/endpoints/secret-rotations/okta-client-secret/list.mdx b/docs/api-reference/endpoints/secret-rotations/okta-client-secret/list.mdx new file mode 100644 index 000000000..bb8b6777f --- /dev/null +++ b/docs/api-reference/endpoints/secret-rotations/okta-client-secret/list.mdx @@ -0,0 +1,4 @@ +--- +title: "List" +openapi: "GET /api/v2/secret-rotations/okta-client-secret" +--- diff --git a/docs/api-reference/endpoints/secret-rotations/okta-client-secret/rotate-secrets.mdx b/docs/api-reference/endpoints/secret-rotations/okta-client-secret/rotate-secrets.mdx new file mode 100644 index 000000000..71f7f2fbf --- /dev/null +++ b/docs/api-reference/endpoints/secret-rotations/okta-client-secret/rotate-secrets.mdx @@ -0,0 +1,4 @@ +--- +title: "Rotate Secrets" +openapi: "POST /api/v2/secret-rotations/okta-client-secret/{rotationId}/rotate-secrets" +--- diff --git a/docs/api-reference/endpoints/secret-rotations/okta-client-secret/update.mdx b/docs/api-reference/endpoints/secret-rotations/okta-client-secret/update.mdx new file mode 100644 index 000000000..3cae3f895 --- /dev/null +++ b/docs/api-reference/endpoints/secret-rotations/okta-client-secret/update.mdx @@ -0,0 +1,8 @@ +--- +title: "Update" +openapi: "PATCH /api/v2/secret-rotations/okta-client-secret/{rotationId}" +--- + + + Check out the configuration docs for [Okta Client Secret Rotations](/documentation/platform/secret-rotation/okta-client-secret) to learn how to obtain the required parameters. + diff --git a/docs/api-reference/endpoints/secret-syncs/bitbucket/create.mdx b/docs/api-reference/endpoints/secret-syncs/bitbucket/create.mdx new file mode 100644 index 000000000..69535ace0 --- /dev/null +++ b/docs/api-reference/endpoints/secret-syncs/bitbucket/create.mdx @@ -0,0 +1,4 @@ +--- +title: "Create" +openapi: "POST /api/v1/secret-syncs/bitbucket" +--- diff --git a/docs/api-reference/endpoints/secret-syncs/bitbucket/delete.mdx b/docs/api-reference/endpoints/secret-syncs/bitbucket/delete.mdx new file mode 100644 index 000000000..55cfc0359 --- /dev/null +++ b/docs/api-reference/endpoints/secret-syncs/bitbucket/delete.mdx @@ -0,0 +1,4 @@ +--- +title: "Delete" +openapi: "DELETE /api/v1/secret-syncs/bitbucket/{syncId}" +--- diff --git a/docs/api-reference/endpoints/secret-syncs/bitbucket/get-by-id.mdx b/docs/api-reference/endpoints/secret-syncs/bitbucket/get-by-id.mdx new file mode 100644 index 000000000..46373e310 --- /dev/null +++ b/docs/api-reference/endpoints/secret-syncs/bitbucket/get-by-id.mdx @@ -0,0 +1,4 @@ +--- +title: "Get by ID" +openapi: "GET /api/v1/secret-syncs/bitbucket/{syncId}" +--- diff --git a/docs/api-reference/endpoints/secret-syncs/bitbucket/get-by-name.mdx b/docs/api-reference/endpoints/secret-syncs/bitbucket/get-by-name.mdx new file mode 100644 index 000000000..82bb47d45 --- /dev/null +++ b/docs/api-reference/endpoints/secret-syncs/bitbucket/get-by-name.mdx @@ -0,0 +1,4 @@ +--- +title: "Get by Name" +openapi: "GET /api/v1/secret-syncs/bitbucket/sync-name/{syncName}" +--- diff --git a/docs/api-reference/endpoints/secret-syncs/bitbucket/import-secrets.mdx b/docs/api-reference/endpoints/secret-syncs/bitbucket/import-secrets.mdx new file mode 100644 index 000000000..eed3d9124 --- /dev/null +++ b/docs/api-reference/endpoints/secret-syncs/bitbucket/import-secrets.mdx @@ -0,0 +1,4 @@ +--- +title: "Import Secrets" +openapi: "POST /api/v1/secret-syncs/bitbucket/{syncId}/import-secrets" +--- diff --git a/docs/api-reference/endpoints/secret-syncs/bitbucket/list.mdx b/docs/api-reference/endpoints/secret-syncs/bitbucket/list.mdx new file mode 100644 index 000000000..98bf3fdda --- /dev/null +++ b/docs/api-reference/endpoints/secret-syncs/bitbucket/list.mdx @@ -0,0 +1,4 @@ +--- +title: "List" +openapi: "GET /api/v1/secret-syncs/bitbucket" +--- diff --git a/docs/api-reference/endpoints/secret-syncs/bitbucket/remove-secrets.mdx b/docs/api-reference/endpoints/secret-syncs/bitbucket/remove-secrets.mdx new file mode 100644 index 000000000..3d52e14e2 --- /dev/null +++ b/docs/api-reference/endpoints/secret-syncs/bitbucket/remove-secrets.mdx @@ -0,0 +1,4 @@ +--- +title: "Remove Secrets" +openapi: "POST /api/v1/secret-syncs/bitbucket/{syncId}/remove-secrets" +--- diff --git a/docs/api-reference/endpoints/secret-syncs/bitbucket/sync-secrets.mdx b/docs/api-reference/endpoints/secret-syncs/bitbucket/sync-secrets.mdx new file mode 100644 index 000000000..47fee7642 --- /dev/null +++ b/docs/api-reference/endpoints/secret-syncs/bitbucket/sync-secrets.mdx @@ -0,0 +1,4 @@ +--- +title: "Sync Secrets" +openapi: "POST /api/v1/secret-syncs/bitbucket/{syncId}/sync-secrets" +--- diff --git a/docs/api-reference/endpoints/secret-syncs/bitbucket/update.mdx b/docs/api-reference/endpoints/secret-syncs/bitbucket/update.mdx new file mode 100644 index 000000000..c9dfac1c8 --- /dev/null +++ b/docs/api-reference/endpoints/secret-syncs/bitbucket/update.mdx @@ -0,0 +1,4 @@ +--- +title: "Update" +openapi: "PATCH /api/v1/secret-syncs/bitbucket/{syncId}" +--- diff --git a/docs/docs.json b/docs/docs.json index a32453c89..e8f6745c3 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -78,7 +78,10 @@ }, { "group": "Infisical SSH", - "pages": ["documentation/platform/ssh/overview", "documentation/platform/ssh/host-groups"] + "pages": [ + "documentation/platform/ssh/overview", + "documentation/platform/ssh/host-groups" + ] }, { "group": "Key Management (KMS)", @@ -146,6 +149,7 @@ "documentation/platform/secret-rotation/ldap-password", "documentation/platform/secret-rotation/mssql-credentials", "documentation/platform/secret-rotation/mysql-credentials", + "documentation/platform/secret-rotation/okta-client-secret", "documentation/platform/secret-rotation/oracledb-credentials", "documentation/platform/secret-rotation/postgres-credentials" ] @@ -375,7 +379,10 @@ }, { "group": "Architecture", - "pages": ["internals/architecture/components", "internals/architecture/cloud"] + "pages": [ + "internals/architecture/components", + "internals/architecture/cloud" + ] }, "internals/security", "internals/service-tokens" @@ -481,6 +488,7 @@ "integrations/app-connections/mssql", "integrations/app-connections/mysql", "integrations/app-connections/oci", + "integrations/app-connections/okta", "integrations/app-connections/oracledb", "integrations/app-connections/postgres", "integrations/app-connections/railway", @@ -508,6 +516,7 @@ "integrations/secret-syncs/azure-app-configuration", "integrations/secret-syncs/azure-devops", "integrations/secret-syncs/azure-key-vault", + "integrations/secret-syncs/bitbucket", "integrations/secret-syncs/camunda", "integrations/secret-syncs/checkly", "integrations/secret-syncs/cloudflare-pages", @@ -551,7 +560,10 @@ "integrations/cloud/gcp-secret-manager", { "group": "Cloudflare", - "pages": ["integrations/cloud/cloudflare-pages", "integrations/cloud/cloudflare-workers"] + "pages": [ + "integrations/cloud/cloudflare-pages", + "integrations/cloud/cloudflare-workers" + ] }, "integrations/cloud/terraform-cloud", "integrations/cloud/databricks", @@ -663,7 +675,11 @@ "cli/commands/reset", { "group": "infisical scan", - "pages": ["cli/commands/scan", "cli/commands/scan-git-changes", "cli/commands/scan-install"] + "pages": [ + "cli/commands/scan", + "cli/commands/scan-git-changes", + "cli/commands/scan-install" + ] } ] }, @@ -987,7 +1003,9 @@ "pages": [ { "group": "Kubernetes", - "pages": ["api-reference/endpoints/dynamic-secrets/kubernetes/create-lease"] + "pages": [ + "api-reference/endpoints/dynamic-secrets/kubernetes/create-lease" + ] }, "api-reference/endpoints/dynamic-secrets/create", "api-reference/endpoints/dynamic-secrets/update", @@ -1093,6 +1111,19 @@ "api-reference/endpoints/secret-rotations/mysql-credentials/update" ] }, + { + "group": "Okta Client Secret", + "pages": [ + "api-reference/endpoints/secret-rotations/okta-client-secret/create", + "api-reference/endpoints/secret-rotations/okta-client-secret/delete", + "api-reference/endpoints/secret-rotations/okta-client-secret/get-by-id", + "api-reference/endpoints/secret-rotations/okta-client-secret/get-by-name", + "api-reference/endpoints/secret-rotations/okta-client-secret/get-generated-credentials-by-id", + "api-reference/endpoints/secret-rotations/okta-client-secret/list", + "api-reference/endpoints/secret-rotations/okta-client-secret/rotate-secrets", + "api-reference/endpoints/secret-rotations/okta-client-secret/update" + ] + }, { "group": "OracleDB Credentials", "pages": [ @@ -1496,6 +1527,18 @@ "api-reference/endpoints/app-connections/oci/delete" ] }, + { + "group": "Okta", + "pages": [ + "api-reference/endpoints/app-connections/okta/list", + "api-reference/endpoints/app-connections/okta/available", + "api-reference/endpoints/app-connections/okta/get-by-id", + "api-reference/endpoints/app-connections/okta/get-by-name", + "api-reference/endpoints/app-connections/okta/create", + "api-reference/endpoints/app-connections/okta/update", + "api-reference/endpoints/app-connections/okta/delete" + ] + }, { "group": "OracleDB", "pages": [ @@ -1707,6 +1750,20 @@ "api-reference/endpoints/secret-syncs/azure-key-vault/remove-secrets" ] }, + { + "group": "Bitbucket", + "pages": [ + "api-reference/endpoints/secret-syncs/bitbucket/list", + "api-reference/endpoints/secret-syncs/bitbucket/get-by-id", + "api-reference/endpoints/secret-syncs/bitbucket/get-by-name", + "api-reference/endpoints/secret-syncs/bitbucket/create", + "api-reference/endpoints/secret-syncs/bitbucket/update", + "api-reference/endpoints/secret-syncs/bitbucket/delete", + "api-reference/endpoints/secret-syncs/bitbucket/sync-secrets", + "api-reference/endpoints/secret-syncs/bitbucket/import-secrets", + "api-reference/endpoints/secret-syncs/bitbucket/remove-secrets" + ] + }, { "group": "Camunda", "pages": [ @@ -2228,6 +2285,7 @@ "sdks/languages/java", "sdks/languages/csharp", "sdks/languages/cpp", + "sdks/languages/rust", "sdks/languages/go", "sdks/languages/ruby" ] diff --git a/docs/documentation/getting-started/sdks.mdx b/docs/documentation/getting-started/sdks.mdx index b3e8a3925..e91ff1906 100644 --- a/docs/documentation/getting-started/sdks.mdx +++ b/docs/documentation/getting-started/sdks.mdx @@ -13,9 +13,12 @@ Prerequisites: Follow the instructions for your language use the SDK for it: -- [Node SDK](https://infisical.com/docs/sdks/languages/node) +- [Node.js SDK](https://infisical.com/docs/sdks/languages/node) - [Python SDK](https://infisical.com/docs/sdks/languages/python) - [Java SDK](https://infisical.com/docs/sdks/languages/java) - [.NET SDK](https://infisical.com/docs/sdks/languages/csharp) +- [Go SDK](https://infisical.com/docs/sdks/languages/go) +- [C++ SDK](https://infisical.com/docs/sdks/languages/cpp) +- [Ruby SDK](https://infisical.com/docs/sdks/languages/ruby) Missing a language? [Throw in a request here](https://github.com/Infisical/infisical/issues). diff --git a/docs/documentation/platform/secret-rotation/okta-client-secret.mdx b/docs/documentation/platform/secret-rotation/okta-client-secret.mdx new file mode 100644 index 000000000..d1f4b159e --- /dev/null +++ b/docs/documentation/platform/secret-rotation/okta-client-secret.mdx @@ -0,0 +1,145 @@ +--- +title: "Okta Client Secret" +description: "Learn how to automatically rotate Okta Client Secrets." +--- + +## Prerequisites + +- Create an [Okta Connection](/integrations/app-connections/okta). + +## Create an Okta Client Secret Rotation in Infisical + + + + 1. Navigate to your Secret Manager Project's Dashboard and select **Add Secret Rotation** from the actions dropdown. + +  + + 2. Select the **Okta Client Secret** option. + +  + + 3. Configure the rotation behavior, then click **Next**. + +  + + - **Okta Connection** - the connection that will perform the rotation of the specified application's Client Secret. + - **Rotation Interval** - the interval, in days, that once elapsed will trigger a rotation. + - **Rotate At** - the local time of day when rotation should occur once the interval has elapsed. + - **Auto-Rotation Enabled** - whether secrets should automatically be rotated once the rotation interval has elapsed. Disable this option to manually rotate secrets or pause secret rotation. + + 4. Select the Okta application whose Client Secret you want to rotate. Then click **Next**. + +  + + 5. Specify the secret names that the client credentials should be mapped to. Then click **Next**. + +  + + - **Client ID** - the name of the secret that the application Client ID will be mapped to. + - **Client Secret** - the name of the secret that the rotated Client Secret will be mapped to. + + 6. Give your rotation a name and description (optional). Then click **Next**. + +  + + - **Name** - the name of the secret rotation configuration. Must be slug-friendly. + - **Description** (optional) - a description of this rotation configuration. + + 7. Review your configuration, then click **Create Secret Rotation**. + +  + + 8. Your **Okta Client Secret** credentials are now available for use via the mapped secrets. + +  + + + To create an Okta Client Secret Rotation, make an API request to the [Create Okta Client Secret Rotation](/api-reference/endpoints/secret-rotations/okta-client-secret/create) API endpoint. + + You will first need the **Client ID** of the Okta application you want to rotate the secret for. This can be obtained from the applications dashboard. + +  + + ### Sample request + + ```bash Request + curl --request POST \ + --url https://us.infisical.com/api/v2/secret-rotations/okta-client-secret \ + --header 'Content-Type: application/json' \ + --data '{ + "name": "my-okta-rotation", + "projectId": "3c90c3cc-0d44-4b50-8888-8dd25736052a", + "description": "my client secret rotation", + "connectionId": "3c90c3cc-0d44-4b50-8888-8dd25736052a", + "environment": "dev", + "secretPath": "/", + "isAutoRotationEnabled": true, + "rotationInterval": 30, + "rotateAtUtc": { + "hours": 0, + "minutes": 0 + }, + "parameters": { + "clientId": "...", + }, + "secretsMapping": { + "clientId": "OKTA_CLIENT_ID", + "clientSecret": "OKTA_CLIENT_SECRET" + } + }' + ``` + + ### Sample response + + ```bash Response + { + "secretRotation": { + "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a", + "name": "my-okta-rotation", + "description": "my client secret rotation", + "secretsMapping": { + "clientId": "OKTA_CLIENT_ID", + "clientSecret": "OKTA_CLIENT_SECRET" + }, + "isAutoRotationEnabled": true, + "activeIndex": 0, + "folderId": "3c90c3cc-0d44-4b50-8888-8dd25736052a", + "connectionId": "3c90c3cc-0d44-4b50-8888-8dd25736052a", + "createdAt": "2023-11-07T05:31:56Z", + "updatedAt": "2023-11-07T05:31:56Z", + "rotationInterval": 30, + "rotationStatus": "success", + "lastRotationAttemptedAt": "2023-11-07T05:31:56Z", + "lastRotatedAt": "2023-11-07T05:31:56Z", + "lastRotationJobId": "3c90c3cc-0d44-4b50-8888-8dd25736052a", + "nextRotationAt": "2023-11-07T05:31:56Z", + "connection": { + "app": "okta", + "name": "my-okta-connection", + "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a" + }, + "environment": { + "slug": "dev", + "name": "Development", + "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a" + }, + "projectId": "3c90c3cc-0d44-4b50-8888-8dd25736052a", + "folder": { + "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a", + "path": "/" + }, + "rotateAtUtc": { + "hours": 0, + "minutes": 0 + }, + "lastRotationMessage": null, + "type": "okta-client-secret", + "parameters": { + "clientId": "..." + } + } + } + ``` + + diff --git a/docs/images/app-connections/bitbucket/step-4-secret-sync.png b/docs/images/app-connections/bitbucket/step-4-secret-sync.png new file mode 100644 index 000000000..5f8f81534 Binary files /dev/null and b/docs/images/app-connections/bitbucket/step-4-secret-sync.png differ diff --git a/docs/images/app-connections/okta/step-1.png b/docs/images/app-connections/okta/step-1.png new file mode 100644 index 000000000..478e87705 Binary files /dev/null and b/docs/images/app-connections/okta/step-1.png differ diff --git a/docs/images/app-connections/okta/step-2.png b/docs/images/app-connections/okta/step-2.png new file mode 100644 index 000000000..69645bf84 Binary files /dev/null and b/docs/images/app-connections/okta/step-2.png differ diff --git a/docs/images/app-connections/okta/step-3.png b/docs/images/app-connections/okta/step-3.png new file mode 100644 index 000000000..de8d69a24 Binary files /dev/null and b/docs/images/app-connections/okta/step-3.png differ diff --git a/docs/images/app-connections/okta/step-4.png b/docs/images/app-connections/okta/step-4.png new file mode 100644 index 000000000..eb6426a37 Binary files /dev/null and b/docs/images/app-connections/okta/step-4.png differ diff --git a/docs/images/app-connections/okta/step-5.png b/docs/images/app-connections/okta/step-5.png new file mode 100644 index 000000000..54bf24bde Binary files /dev/null and b/docs/images/app-connections/okta/step-5.png differ diff --git a/docs/images/sdks/languages/cpp.svg b/docs/images/sdks/languages/cpp.svg new file mode 100644 index 000000000..caced490f --- /dev/null +++ b/docs/images/sdks/languages/cpp.svg @@ -0,0 +1,11 @@ + + + C++ + + + + + + + + diff --git a/docs/images/sdks/languages/dotnet.svg b/docs/images/sdks/languages/dotnet.svg new file mode 100644 index 000000000..c864d45d2 --- /dev/null +++ b/docs/images/sdks/languages/dotnet.svg @@ -0,0 +1,8 @@ + + + .NET + + + + + diff --git a/docs/images/sdks/languages/go.svg b/docs/images/sdks/languages/go.svg new file mode 100644 index 000000000..ec964ffc3 --- /dev/null +++ b/docs/images/sdks/languages/go.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/docs/images/sdks/languages/java.svg b/docs/images/sdks/languages/java.svg new file mode 100644 index 000000000..228b75f6b --- /dev/null +++ b/docs/images/sdks/languages/java.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/docs/images/sdks/languages/node.svg b/docs/images/sdks/languages/node.svg new file mode 100644 index 000000000..abf449bce --- /dev/null +++ b/docs/images/sdks/languages/node.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/docs/images/sdks/languages/python.svg b/docs/images/sdks/languages/python.svg new file mode 100644 index 000000000..cfbb36f36 --- /dev/null +++ b/docs/images/sdks/languages/python.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/docs/images/sdks/languages/ruby.svg b/docs/images/sdks/languages/ruby.svg new file mode 100644 index 000000000..eaae0bdbc --- /dev/null +++ b/docs/images/sdks/languages/ruby.svg @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/images/sdks/languages/rust.svg b/docs/images/sdks/languages/rust.svg new file mode 100644 index 000000000..1410406a1 --- /dev/null +++ b/docs/images/sdks/languages/rust.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/docs/images/secret-rotations-v2/okta-client-secret/client-id.png b/docs/images/secret-rotations-v2/okta-client-secret/client-id.png new file mode 100644 index 000000000..83ac00c4f Binary files /dev/null and b/docs/images/secret-rotations-v2/okta-client-secret/client-id.png differ diff --git a/docs/images/secret-rotations-v2/okta-client-secret/configuration.png b/docs/images/secret-rotations-v2/okta-client-secret/configuration.png new file mode 100644 index 000000000..fe511bbcc Binary files /dev/null and b/docs/images/secret-rotations-v2/okta-client-secret/configuration.png differ diff --git a/docs/images/secret-rotations-v2/okta-client-secret/created.png b/docs/images/secret-rotations-v2/okta-client-secret/created.png new file mode 100644 index 000000000..4e0c8a5da Binary files /dev/null and b/docs/images/secret-rotations-v2/okta-client-secret/created.png differ diff --git a/docs/images/secret-rotations-v2/okta-client-secret/details.png b/docs/images/secret-rotations-v2/okta-client-secret/details.png new file mode 100644 index 000000000..6eafb89bf Binary files /dev/null and b/docs/images/secret-rotations-v2/okta-client-secret/details.png differ diff --git a/docs/images/secret-rotations-v2/okta-client-secret/mappings.png b/docs/images/secret-rotations-v2/okta-client-secret/mappings.png new file mode 100644 index 000000000..baeaa1605 Binary files /dev/null and b/docs/images/secret-rotations-v2/okta-client-secret/mappings.png differ diff --git a/docs/images/secret-rotations-v2/okta-client-secret/parameters.png b/docs/images/secret-rotations-v2/okta-client-secret/parameters.png new file mode 100644 index 000000000..b5a6a716b Binary files /dev/null and b/docs/images/secret-rotations-v2/okta-client-secret/parameters.png differ diff --git a/docs/images/secret-rotations-v2/okta-client-secret/review.png b/docs/images/secret-rotations-v2/okta-client-secret/review.png new file mode 100644 index 000000000..45462ceb5 Binary files /dev/null and b/docs/images/secret-rotations-v2/okta-client-secret/review.png differ diff --git a/docs/images/secret-rotations-v2/okta-client-secret/select-okta.png b/docs/images/secret-rotations-v2/okta-client-secret/select-okta.png new file mode 100644 index 000000000..34347245f Binary files /dev/null and b/docs/images/secret-rotations-v2/okta-client-secret/select-okta.png differ diff --git a/docs/images/secret-syncs/bitbucket/configure-destination.png b/docs/images/secret-syncs/bitbucket/configure-destination.png new file mode 100644 index 000000000..f393387be Binary files /dev/null and b/docs/images/secret-syncs/bitbucket/configure-destination.png differ diff --git a/docs/images/secret-syncs/bitbucket/configure-details.png b/docs/images/secret-syncs/bitbucket/configure-details.png new file mode 100644 index 000000000..64f9c2720 Binary files /dev/null and b/docs/images/secret-syncs/bitbucket/configure-details.png differ diff --git a/docs/images/secret-syncs/bitbucket/configure-source.png b/docs/images/secret-syncs/bitbucket/configure-source.png new file mode 100644 index 000000000..2b70abba5 Binary files /dev/null and b/docs/images/secret-syncs/bitbucket/configure-source.png differ diff --git a/docs/images/secret-syncs/bitbucket/configure-sync-options.png b/docs/images/secret-syncs/bitbucket/configure-sync-options.png new file mode 100644 index 000000000..471b2851c Binary files /dev/null and b/docs/images/secret-syncs/bitbucket/configure-sync-options.png differ diff --git a/docs/images/secret-syncs/bitbucket/review-configuration.png b/docs/images/secret-syncs/bitbucket/review-configuration.png new file mode 100644 index 000000000..e76c726fa Binary files /dev/null and b/docs/images/secret-syncs/bitbucket/review-configuration.png differ diff --git a/docs/images/secret-syncs/bitbucket/select-option.png b/docs/images/secret-syncs/bitbucket/select-option.png new file mode 100644 index 000000000..85446dd55 Binary files /dev/null and b/docs/images/secret-syncs/bitbucket/select-option.png differ diff --git a/docs/images/secret-syncs/bitbucket/sync-created.png b/docs/images/secret-syncs/bitbucket/sync-created.png new file mode 100644 index 000000000..31afde5be Binary files /dev/null and b/docs/images/secret-syncs/bitbucket/sync-created.png differ diff --git a/docs/integrations/app-connections/bitbucket.mdx b/docs/integrations/app-connections/bitbucket.mdx index e4f9ae29f..be4fdbee7 100644 --- a/docs/integrations/app-connections/bitbucket.mdx +++ b/docs/integrations/app-connections/bitbucket.mdx @@ -47,6 +47,19 @@ Infisical supports the use of [API Tokens](https://support.atlassian.com/bitbuck  + + ``` + read:workspace:bitbucket + admin:workspace:bitbucket + read:user:bitbucket + read:repository:bitbucket + read:pipeline:bitbucket + write:pipeline:bitbucket + admin:pipeline:bitbucket + ``` + +  + Click **Next**. diff --git a/docs/integrations/app-connections/okta.mdx b/docs/integrations/app-connections/okta.mdx new file mode 100644 index 000000000..3c1295cf8 --- /dev/null +++ b/docs/integrations/app-connections/okta.mdx @@ -0,0 +1,99 @@ +--- +title: "Okta Connection" +description: "Learn how to configure an Okta Connection for Infisical." +--- + +Infisical supports the use of [API Tokens](https://developer.okta.com/docs/guides/create-an-api-token/main/) to connect with Okta. + +## Create Okta API Token + + + + From the Okta admin dashboard, navigate to **Security > API > Tokens** and click **Create token**. + +  + + + Enter the token name and select **Any IP** for the second dropdown, then click **Create token**. + +  + + + Copy the token from the modal for later steps. + +  + + + +## Create Okta Connection in Infisical + + + + + + In your Infisical dashboard, go to **Organization Settings** and select the [**App Connections**](https://app.infisical.com/organization/app-connections) tab. + +  + + + Click the **Add Connection** button and select **Okta** from the list of available connections. + + + Complete the Okta Connection form by entering: + - A descriptive name for the connection + - An optional description for future reference + - Your Okta instance URL + - The API Token from earlier steps + +  + + + After clicking Create, your **Okta Connection** is established and ready to use with your Infisical projects. + +  + + + + + To create a Okta Connection, make an API request to the [Create Okta Connection](/api-reference/endpoints/app-connections/okta/create) API endpoint. + + ### Sample request + + ```bash Request + curl --request POST \ + --url https://app.infisical.com/api/v1/app-connections/okta \ + --header 'Content-Type: application/json' \ + --data '{ + "name": "my-okta-connection", + "method": "api-token", + "credentials": { + "instanceUrl": "https://example.okta.com", + "apiToken": "" + } + }' + ``` + + ### Sample response + + ```bash Response + { + "appConnection": { + "id": "e5d18aca-86f7-4026-a95e-efb8aeb0d8e6", + "name": "my-okta-connection", + "description": null, + "version": 1, + "orgId": "6f03caa1-a5de-43ce-b127-95a145d3464c", + "createdAt": "2025-04-23T19:46:34.831Z", + "updatedAt": "2025-04-23T19:46:34.831Z", + "isPlatformManagedCredentials": false, + "credentialsHash": "7c2d371dec195f82a6a0d5b41c970a229cfcaf88e894a5b6395e2dbd0280661f", + "app": "okta", + "method": "api-token", + "credentials": { + "instanceUrl": "https://example.okta.com" + } + } + } + ``` + + diff --git a/docs/integrations/secret-syncs/bitbucket.mdx b/docs/integrations/secret-syncs/bitbucket.mdx new file mode 100644 index 000000000..9793e89c9 --- /dev/null +++ b/docs/integrations/secret-syncs/bitbucket.mdx @@ -0,0 +1,159 @@ +--- +title: "Bitbucket Sync" +description: "Learn how to configure a Bitbucket Sync for Infisical." +--- + +**Prerequisites:** +- Create a [Bitbucket Connection](/integrations/app-connections/bitbucket) + + + + + + Navigate to **Project** > **Integrations** and select the **Secret Syncs** tab. Click on the **Add Sync** button. + +  + + +  + + + Configure the **Source** from where secrets should be retrieved, then click **Next**. + +  + + - **Environment**: The project environment to retrieve secrets from. + - **Secret Path**: The folder path to retrieve secrets from. + + + If you need to sync secrets from multiple folder locations, check out [secret imports](/documentation/platform/secret-reference#secret-imports). + + + + Configure the **Destination** to where secrets should be deployed, then click **Next**. + +  + + - **Bitbucket Connection**: The Bitbucket Connection to authenticate with. + - **Workspace**: The Bitbucket workspace to sync secrets to. + - **Repository**: The Bitbucket repository to sync secrets to. + - **Deployment Environment (Optional)**: The Bitbucket deployment environment to sync secrets to. + + + Configure the **Sync Options** to specify how secrets should be synced, then click **Next**. + +  + + - **Initial Sync Behavior**: Determines how Infisical should resolve the initial sync. + - **Overwrite Destination Secrets**: Removes any secrets at the destination endpoint not present in Infisical. + + Bitbucket does not support importing secrets. + + - **Key Schema**: Template that determines how secret names are transformed when syncing, using `{{secretKey}}` as a placeholder for the original secret name and `{{environment}}` for the environment. + + We highly recommend using a Key Schema to ensure that Infisical only manages the specific keys you intend, keeping everything else untouched. + + - **Auto-Sync Enabled**: If enabled, secrets will automatically be synced from the source location when changes occur. Disable to enforce manual syncing only. + - **Disable Secret Deletion**: If enabled, Infisical will not remove secrets from the sync destination. Enable this option if you intend to manage some secrets manually outside of Infisical. + + + Configure the **Details** of your Bitbucket Sync, then click **Next**. + +  + + - **Name**: The name of your sync. Must be slug-friendly. + - **Description**: An optional description for your sync. + + + Review your Bitbucket Sync configuration, then click **Create Sync**. + +  + + + If enabled, your Bitbucket Sync will begin syncing your secrets to the destination endpoint. + +  + + + + + To create a **Bitbucket Sync**, make an API request to the [Create Bitbucket Sync](/api-reference/endpoints/secret-syncs/bitbucket/create) API endpoint. + + ### Sample request + + ```bash Request + curl --request POST \ + --url https://app.infisical.com/api/v1/secret-syncs/bitbucket \ + --header 'Content-Type: application/json' \ + --data '{ + "name": "my-bitbucket-sync", + "projectId": "3c90c3cc-0d44-4b50-8888-8dd25736052a", + "description": "an example sync", + "connectionId": "3c90c3cc-0d44-4b50-8888-8dd25736052a", + "environment": "dev", + "secretPath": "/my-secrets", + "isEnabled": true, + "syncOptions": { + "initialSyncBehavior": "overwrite-destination" + }, + "destinationConfig": { + "workspaceSlug": "my-bitbucket-workspace", + "repositorySlug": "my-bitbucket-repository" + } + }' + ``` + + ### Sample response + + ```bash Response + { + "secretSync": { + "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a", + "name": "my-bitbucket-sync", + "description": "an example sync", + "isEnabled": true, + "version": 1, + "folderId": "3c90c3cc-0d44-4b50-8888-8dd25736052a", + "connectionId": "3c90c3cc-0d44-4b50-8888-8dd25736052a", + "createdAt": "2023-11-07T05:31:56Z", + "updatedAt": "2023-11-07T05:31:56Z", + "syncStatus": "succeeded", + "lastSyncJobId": "123", + "lastSyncMessage": null, + "lastSyncedAt": "2023-11-07T05:31:56Z", + "importStatus": null, + "lastImportJobId": null, + "lastImportMessage": null, + "lastImportedAt": null, + "removeStatus": null, + "lastRemoveJobId": null, + "lastRemoveMessage": null, + "lastRemovedAt": null, + "syncOptions": { + "initialSyncBehavior": "overwrite-destination" + }, + "projectId": "3c90c3cc-0d44-4b50-8888-8dd25736052a", + "connection": { + "app": "bitbucket", + "name": "my-bitbucket-connection", + "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a" + }, + "environment": { + "slug": "dev", + "name": "Development", + "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a" + }, + "folder": { + "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a", + "path": "/my-secrets" + }, + "destination": "bitbucket", + "destinationConfig": { + "workspaceSlug": "my-bitbucket-workspace", + "repositorySlug": "my-bitbucket-repository" + } + } + } + ``` + + diff --git a/docs/sdks/languages/cpp.mdx b/docs/sdks/languages/cpp.mdx index c75032ab1..2e22def9c 100644 --- a/docs/sdks/languages/cpp.mdx +++ b/docs/sdks/languages/cpp.mdx @@ -2,5 +2,5 @@ title: "Infisical C++ SDK" sidebarTitle: "C++" url: "https://github.com/Infisical/infisical-cpp-sdk/?tab=readme-ov-file#infisical-c-sdk" -icon: "c" +icon: "/images/sdks/languages/cpp.svg" --- \ No newline at end of file diff --git a/docs/sdks/languages/csharp.mdx b/docs/sdks/languages/csharp.mdx index 71ac7337e..524778a4a 100644 --- a/docs/sdks/languages/csharp.mdx +++ b/docs/sdks/languages/csharp.mdx @@ -2,7 +2,7 @@ title: "Infisical .NET SDK" sidebarTitle: ".NET" url: "https://github.com/Infisical/infisical-dotnet-sdk?tab=readme-ov-file#infisical-net-sdk" -icon: "bars" +icon: "/images/sdks/languages/dotnet.svg" --- {/* If you're working with C#, the official [Infisical C# SDK](https://github.com/Infisical/sdk/tree/main/languages/csharp) package is the easiest way to fetch and work with secrets for your application. diff --git a/docs/sdks/languages/go.mdx b/docs/sdks/languages/go.mdx index b12b442a8..312f7e307 100644 --- a/docs/sdks/languages/go.mdx +++ b/docs/sdks/languages/go.mdx @@ -1,7 +1,7 @@ --- title: "Infisical Go SDK" sidebarTitle: "Go" -icon: "golang" +icon: "/images/sdks/languages/go.svg" --- If you're working with Go Lang, the official [Infisical Go SDK](https://github.com/infisical/go-sdk) package is the easiest way to fetch and work with secrets for your application. diff --git a/docs/sdks/languages/java.mdx b/docs/sdks/languages/java.mdx index 8b8ade7b0..359afb987 100644 --- a/docs/sdks/languages/java.mdx +++ b/docs/sdks/languages/java.mdx @@ -2,7 +2,7 @@ title: "Infisical Java SDK" sidebarTitle: "Java" url: "https://github.com/Infisical/java-sdk?tab=readme-ov-file#infisical-java-sdk" -icon: "java" +icon: "/images/sdks/languages/java.svg" --- { diff --git a/docs/sdks/languages/node.mdx b/docs/sdks/languages/node.mdx index c947cb82d..69bb36e97 100644 --- a/docs/sdks/languages/node.mdx +++ b/docs/sdks/languages/node.mdx @@ -2,7 +2,7 @@ title: "Infisical Node.js SDK" sidebarTitle: "Node.js" url: "https://github.com/Infisical/node-sdk-v2?tab=readme-ov-file#infisical-nodejs-sdk" -icon: "node" +icon: "/images/sdks/languages/node.svg" --- {/* diff --git a/docs/sdks/languages/python.mdx b/docs/sdks/languages/python.mdx index f7a2ee90b..f888c0819 100644 --- a/docs/sdks/languages/python.mdx +++ b/docs/sdks/languages/python.mdx @@ -2,7 +2,7 @@ title: "Infisical Python SDK" sidebarTitle: "Python" url: "https://github.com/Infisical/python-sdk-official?tab=readme-ov-file#infisical-python-sdk" -icon: "python" +icon: "/images/sdks/languages/python.svg" --- {/* If you're working with Python, the official [infisical-python](https://github.com/Infisical/sdk/edit/main/crates/infisical-py) package is the easiest way to fetch and work with secrets for your application. diff --git a/docs/sdks/languages/ruby.mdx b/docs/sdks/languages/ruby.mdx index b6fe0863a..5780c48ec 100644 --- a/docs/sdks/languages/ruby.mdx +++ b/docs/sdks/languages/ruby.mdx @@ -1,7 +1,7 @@ --- title: "Infisical Ruby SDK" sidebarTitle: "Ruby" -icon: "diamond" +icon: "/images/sdks/languages/ruby.svg" --- diff --git a/docs/sdks/languages/rust.mdx b/docs/sdks/languages/rust.mdx new file mode 100644 index 000000000..3d2f16175 --- /dev/null +++ b/docs/sdks/languages/rust.mdx @@ -0,0 +1,6 @@ +--- +title: "Infisical Rust SDK" +sidebarTitle: "Rust" +icon: "/images/sdks/languages/rust.svg" +url: "https://github.com/Infisical/rust-sdk?tab=readme-ov-file#infisical--the-official-infisical-rust-sdk" +--- \ No newline at end of file diff --git a/docs/sdks/overview.mdx b/docs/sdks/overview.mdx index 3d91713da..32192805d 100644 --- a/docs/sdks/overview.mdx +++ b/docs/sdks/overview.mdx @@ -3,6 +3,8 @@ title: "SDKs" sidebarTitle: "Introduction" --- + + From local development to production, Infisical SDKs provide the easiest way for your app to fetch back secrets from Infisical on demand. - Install and initialize a language-specific client SDK into your application @@ -10,29 +12,36 @@ From local development to production, Infisical SDKs provide the easiest way for - Fetch secrets on demand - + Manage secrets for your Node application on demand - + Manage secrets for your Python application on demand - + Manage secrets for your Java application on demand - - Manage secrets for your Go application on demand - - + Manage secrets for your .NET application on demand - + Manage secrets for your C++ application on demand - + + Manage secrets for your Rust application on demand + + + Manage secrets for your Go application on demand + + Manage secrets for your Ruby application on demand + + We're always looking for new languages to support. If you'd like to see a new language added, please let us know by opening an issue on our [GitHub repository](https://github.com/Infisical/infisical/issues). + + ## FAQ diff --git a/frontend/public/images/integrations/Okta.png b/frontend/public/images/integrations/Okta.png new file mode 100644 index 000000000..d742d4347 Binary files /dev/null and b/frontend/public/images/integrations/Okta.png differ diff --git a/frontend/src/components/navigation/NavHeader.tsx b/frontend/src/components/navigation/NavHeader.tsx index 326dbc10e..1283c02d1 100644 --- a/frontend/src/components/navigation/NavHeader.tsx +++ b/frontend/src/components/navigation/NavHeader.tsx @@ -6,7 +6,6 @@ import { twMerge } from "tailwind-merge"; import { useOrganization, useWorkspace } from "@app/context"; import { useToggle } from "@app/hooks"; -import { ProjectType } from "@app/hooks/api/workspace/types"; import { createNotification } from "../notifications"; import { IconButton, Select, SelectItem, Tooltip } from "../v2"; @@ -93,7 +92,7 @@ export default function NavHeader({ {pageName === "Secrets" ? ( @@ -129,7 +128,7 @@ export default function NavHeader({ @@ -191,7 +190,7 @@ export default function NavHeader({ ) : ( ) : ( - ( - - onChange(e)} - className="w-full max-w-md bg-mineshaft-800" - > - Secrets Manager - PKI Manager - KMS - SSH - Secret Scanning - - - )} - /> ; +const PROJECT_TYPE_MENU_ITEMS = [ + { + label: "Secrets Management", + value: ProjectType.SecretManager + }, + { + label: "Cert Management", + value: ProjectType.CertificateManager + }, + { + label: "KMS", + value: ProjectType.KMS + }, + { + label: "SSH", + value: ProjectType.SSH + }, + { + label: "Secret Scanning", + value: ProjectType.SecretScanning + } +]; + const NewProjectForm = ({ onOpenChange }: NewProjectFormProps) => { const navigate = useNavigate(); const { currentOrg } = useOrganization(); @@ -70,18 +97,11 @@ const NewProjectForm = ({ onOpenChange }: NewProjectFormProps) => { OrgPermissionSubjects.ProjectTemplates ); - const { data: projectTemplates = [] } = useListProjectTemplates({ - enabled: Boolean(canReadProjectTemplates && subscription?.projectTemplates) - }); - - const { data: externalKmsList } = useGetExternalKmsList(currentOrg.id, { - enabled: permission.can(OrgPermissionActions.Read, OrgPermissionSubjects.Kms) - }); - const { control, handleSubmit, reset, + watch, formState: { isSubmitting, errors } } = useForm({ resolver: zodResolver(formSchema), @@ -91,6 +111,16 @@ const NewProjectForm = ({ onOpenChange }: NewProjectFormProps) => { } }); + const selectedProjectType = watch("type"); + const { data: projectTemplates = [] } = useListProjectTemplates({ + enabled: Boolean(canReadProjectTemplates && subscription?.projectTemplates), + select: (template) => template.filter((el) => el.type === selectedProjectType) + }); + + const { data: externalKmsList } = useGetExternalKmsList(currentOrg.id, { + enabled: permission.can(OrgPermissionActions.Read, OrgPermissionSubjects.Kms) + }); + useEffect(() => { if (Object.keys(errors).length > 0) { console.log("Current form errors:", errors); @@ -101,7 +131,8 @@ const NewProjectForm = ({ onOpenChange }: NewProjectFormProps) => { name, description, kmsKeyId, - template + template, + type }: TAddProjectFormData) => { // type check if (!currentOrg) return; @@ -113,7 +144,8 @@ const NewProjectForm = ({ onOpenChange }: NewProjectFormProps) => { projectName: name, projectDescription: description, kmsKeyId: kmsKeyId !== INTERNAL_KMS_KEY_ID ? kmsKeyId : undefined, - template + template, + type }); await refetchWorkspaces(); @@ -121,7 +153,7 @@ const NewProjectForm = ({ onOpenChange }: NewProjectFormProps) => { reset(); onOpenChange(false); navigate({ - to: getProjectHomePage(project.defaultProduct), + to: getProjectHomePage(project.type), params: { projectId: project.id } }); } catch (err) { @@ -150,6 +182,42 @@ const NewProjectForm = ({ onOpenChange }: NewProjectFormProps) => { )} /> + ( + + + {PROJECT_TYPE_MENU_ITEMS.map((el) => ( + field.onChange(el.value)} + role="button" + tabIndex={0} + onKeyDown={(e) => { + if (e.key === "Enter") { + field.onChange(el.value); + } + }} + > + + {el.label} + + ))} + + + )} + /> { )} /> + { + const inactiveIndex = activeIndex === 0 ? 1 : 0; + + const activeCredentials = generatedCredentials[activeIndex]; + const inactiveCredentials = generatedCredentials[inactiveIndex]; + + return ( + + {activeCredentials?.clientId} + + {activeCredentials?.clientSecret} + + > + } + inactiveCredentials={ + <> + {inactiveCredentials?.clientId} + + {inactiveCredentials?.clientSecret} + + > + } + /> + ); +}; diff --git a/frontend/src/components/secret-rotations-v2/ViewSecretRotationV2GeneratedCredentials/ViewSecretRotationV2GeneratedCredentials.tsx b/frontend/src/components/secret-rotations-v2/ViewSecretRotationV2GeneratedCredentials/ViewSecretRotationV2GeneratedCredentials.tsx index c81eb9920..33d3fccc1 100644 --- a/frontend/src/components/secret-rotations-v2/ViewSecretRotationV2GeneratedCredentials/ViewSecretRotationV2GeneratedCredentials.tsx +++ b/frontend/src/components/secret-rotations-v2/ViewSecretRotationV2GeneratedCredentials/ViewSecretRotationV2GeneratedCredentials.tsx @@ -22,6 +22,7 @@ import { import { ViewSqlCredentialsRotationGeneratedCredentials } from "./shared"; import { ViewAwsIamUserSecretRotationGeneratedCredentials } from "./ViewAwsIamUserSecretRotationGeneratedCredentials"; +import { ViewOktaClientSecretRotationGeneratedCredentials } from "./ViewOktaClientSecretRotationGeneratedCredentials"; type Props = { secretRotation?: TSecretRotationV2; @@ -99,6 +100,13 @@ const Content = ({ secretRotation }: ContentProps) => { /> ); break; + case SecretRotation.OktaClientSecret: + Component = ( + + ); + break; default: throw new Error("Unhandled View Generated Credential Rotation Type"); } diff --git a/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2ParametersFields/OktaClientSecretRotationParametersFields.tsx b/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2ParametersFields/OktaClientSecretRotationParametersFields.tsx new file mode 100644 index 000000000..bb306615d --- /dev/null +++ b/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2ParametersFields/OktaClientSecretRotationParametersFields.tsx @@ -0,0 +1,51 @@ +import { Controller, useFormContext } from "react-hook-form"; +import { SingleValue } from "react-select"; + +import { TSecretRotationV2Form } from "@app/components/secret-rotations-v2/forms/schemas"; +import { FilterableSelect, FormControl } from "@app/components/v2"; +import { useOktaConnectionListApps } from "@app/hooks/api/appConnections/okta"; +import { TOktaApp } from "@app/hooks/api/appConnections/okta/types"; +import { SecretRotation } from "@app/hooks/api/secretRotationsV2"; + +export const OktaClientSecretRotationParametersFields = () => { + const { control, watch, setValue } = useFormContext< + TSecretRotationV2Form & { + type: SecretRotation.OktaClientSecret; + } + >(); + + const connectionId = watch("connection.id"); + + const { data: apps, isPending: isAppsPending } = useOktaConnectionListApps(connectionId, { + enabled: Boolean(connectionId) + }); + + return ( + ( + + app.id === value) ?? null} + onChange={(option) => { + onChange((option as SingleValue)?.id ?? null); + setValue("parameters.clientId", (option as SingleValue)?.id ?? ""); + }} + options={apps} + placeholder="Select an application..." + getOptionLabel={(option) => option.label} + getOptionValue={(option) => option.id} + /> + + )} + /> + ); +}; diff --git a/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2ParametersFields/SecretRotationV2ParametersFields.tsx b/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2ParametersFields/SecretRotationV2ParametersFields.tsx index 959ca2d9e..3f489b04e 100644 --- a/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2ParametersFields/SecretRotationV2ParametersFields.tsx +++ b/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2ParametersFields/SecretRotationV2ParametersFields.tsx @@ -7,6 +7,7 @@ import { Auth0ClientSecretRotationParametersFields } from "./Auth0ClientSecretRo import { AwsIamUserSecretRotationParametersFields } from "./AwsIamUserSecretRotationParametersFields"; import { AzureClientSecretRotationParametersFields } from "./AzureClientSecretRotationParametersFields"; import { LdapPasswordRotationParametersFields } from "./LdapPasswordRotationParametersFields"; +import { OktaClientSecretRotationParametersFields } from "./OktaClientSecretRotationParametersFields"; import { SqlCredentialsRotationParametersFields } from "./shared"; const COMPONENT_MAP: Record = { @@ -17,7 +18,8 @@ const COMPONENT_MAP: Record = { [SecretRotation.Auth0ClientSecret]: Auth0ClientSecretRotationParametersFields, [SecretRotation.AzureClientSecret]: AzureClientSecretRotationParametersFields, [SecretRotation.LdapPassword]: LdapPasswordRotationParametersFields, - [SecretRotation.AwsIamUserSecret]: AwsIamUserSecretRotationParametersFields + [SecretRotation.AwsIamUserSecret]: AwsIamUserSecretRotationParametersFields, + [SecretRotation.OktaClientSecret]: OktaClientSecretRotationParametersFields }; export const SecretRotationV2ParametersFields = () => { diff --git a/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2ReviewFields/OktaClientSecretRotationReviewFields.tsx b/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2ReviewFields/OktaClientSecretRotationReviewFields.tsx new file mode 100644 index 000000000..a9fc4068e --- /dev/null +++ b/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2ReviewFields/OktaClientSecretRotationReviewFields.tsx @@ -0,0 +1,29 @@ +import { useFormContext } from "react-hook-form"; + +import { TSecretRotationV2Form } from "@app/components/secret-rotations-v2/forms/schemas"; +import { GenericFieldLabel } from "@app/components/v2"; +import { SecretRotation } from "@app/hooks/api/secretRotationsV2"; + +import { SecretRotationReviewSection } from "./shared"; + +export const OktaClientSecretRotationReviewFields = () => { + const { watch } = useFormContext< + TSecretRotationV2Form & { + type: SecretRotation.OktaClientSecret; + } + >(); + + const [parameters, { clientId, clientSecret }] = watch(["parameters", "secretsMapping"]); + + return ( + <> + + {parameters.clientId} + + + {clientId} + {clientSecret} + + > + ); +}; diff --git a/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2ReviewFields/SecretRotationReviewFields.tsx b/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2ReviewFields/SecretRotationReviewFields.tsx index 17cc34f27..636cc98cc 100644 --- a/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2ReviewFields/SecretRotationReviewFields.tsx +++ b/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2ReviewFields/SecretRotationReviewFields.tsx @@ -10,6 +10,7 @@ import { Auth0ClientSecretRotationReviewFields } from "./Auth0ClientSecretRotati import { AwsIamUserSecretRotationReviewFields } from "./AwsIamUserSecretRotationReviewFields"; import { AzureClientSecretRotationReviewFields } from "./AzureClientSecretRotationReviewFields"; import { LdapPasswordRotationReviewFields } from "./LdapPasswordRotationReviewFields"; +import { OktaClientSecretRotationReviewFields } from "./OktaClientSecretRotationReviewFields"; import { SqlCredentialsRotationReviewFields } from "./shared"; const COMPONENT_MAP: Record = { @@ -20,7 +21,8 @@ const COMPONENT_MAP: Record = { [SecretRotation.Auth0ClientSecret]: Auth0ClientSecretRotationReviewFields, [SecretRotation.AzureClientSecret]: AzureClientSecretRotationReviewFields, [SecretRotation.LdapPassword]: LdapPasswordRotationReviewFields, - [SecretRotation.AwsIamUserSecret]: AwsIamUserSecretRotationReviewFields + [SecretRotation.AwsIamUserSecret]: AwsIamUserSecretRotationReviewFields, + [SecretRotation.OktaClientSecret]: OktaClientSecretRotationReviewFields }; export const SecretRotationV2ReviewFields = () => { diff --git a/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2SecretsMappingFields/OktaClientSecretRotationSecretsMappingFields.tsx b/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2SecretsMappingFields/OktaClientSecretRotationSecretsMappingFields.tsx new file mode 100644 index 000000000..72adc863d --- /dev/null +++ b/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2SecretsMappingFields/OktaClientSecretRotationSecretsMappingFields.tsx @@ -0,0 +1,58 @@ +import { Controller, useFormContext } from "react-hook-form"; + +import { TSecretRotationV2Form } from "@app/components/secret-rotations-v2/forms/schemas"; +import { FormControl, Input } from "@app/components/v2"; +import { SecretRotation, useSecretRotationV2Option } from "@app/hooks/api/secretRotationsV2"; + +import { SecretsMappingTable } from "./shared"; + +export const OktaClientSecretRotationSecretsMappingFields = () => { + const { control } = useFormContext< + TSecretRotationV2Form & { + type: SecretRotation.OktaClientSecret; + } + >(); + + const { rotationOption } = useSecretRotationV2Option(SecretRotation.OktaClientSecret); + + const items = [ + { + name: "Client ID", + input: ( + ( + + + + )} + control={control} + name="secretsMapping.clientId" + /> + ) + }, + { + name: "Client Secret", + input: ( + ( + + + + )} + control={control} + name="secretsMapping.clientSecret" + /> + ) + } + ]; + + return ; +}; diff --git a/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2SecretsMappingFields/SecretRotationV2SecretsMappingFields.tsx b/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2SecretsMappingFields/SecretRotationV2SecretsMappingFields.tsx index 428a99161..dd0ce9cab 100644 --- a/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2SecretsMappingFields/SecretRotationV2SecretsMappingFields.tsx +++ b/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2SecretsMappingFields/SecretRotationV2SecretsMappingFields.tsx @@ -7,6 +7,7 @@ import { Auth0ClientSecretRotationSecretsMappingFields } from "./Auth0ClientSecr import { AwsIamUserSecretRotationSecretsMappingFields } from "./AwsIamUserSecretRotationSecretsMappingFields"; import { AzureClientSecretRotationSecretsMappingFields } from "./AzureClientSecretRotationSecretsMappingFields"; import { LdapPasswordRotationSecretsMappingFields } from "./LdapPasswordRotationSecretsMappingFields"; +import { OktaClientSecretRotationSecretsMappingFields } from "./OktaClientSecretRotationSecretsMappingFields"; import { SqlCredentialsRotationSecretsMappingFields } from "./shared"; const COMPONENT_MAP: Record = { @@ -17,7 +18,8 @@ const COMPONENT_MAP: Record = { [SecretRotation.Auth0ClientSecret]: Auth0ClientSecretRotationSecretsMappingFields, [SecretRotation.AzureClientSecret]: AzureClientSecretRotationSecretsMappingFields, [SecretRotation.LdapPassword]: LdapPasswordRotationSecretsMappingFields, - [SecretRotation.AwsIamUserSecret]: AwsIamUserSecretRotationSecretsMappingFields + [SecretRotation.AwsIamUserSecret]: AwsIamUserSecretRotationSecretsMappingFields, + [SecretRotation.OktaClientSecret]: OktaClientSecretRotationSecretsMappingFields }; export const SecretRotationV2SecretsMappingFields = () => { diff --git a/frontend/src/components/secret-rotations-v2/forms/schemas/index.ts b/frontend/src/components/secret-rotations-v2/forms/schemas/index.ts index 77151bf1e..a6ebe2f64 100644 --- a/frontend/src/components/secret-rotations-v2/forms/schemas/index.ts +++ b/frontend/src/components/secret-rotations-v2/forms/schemas/index.ts @@ -10,6 +10,7 @@ import { PostgresCredentialsRotationSchema } from "@app/components/secret-rotati import { SecretRotation } from "@app/hooks/api/secretRotationsV2"; import { LdapPasswordRotationMethod } from "@app/hooks/api/secretRotationsV2/types/ldap-password-rotation"; +import { OktaClientSecretRotationSchema } from "./okta-client-secret-rotation-schema"; import { OracleDBCredentialsRotationSchema } from "./oracledb-credentials-rotation-schema"; export const SecretRotationV2FormSchema = (isUpdate: boolean) => @@ -23,7 +24,8 @@ export const SecretRotationV2FormSchema = (isUpdate: boolean) => MySqlCredentialsRotationSchema, OracleDBCredentialsRotationSchema, LdapPasswordRotationSchema, - AwsIamUserSecretRotationSchema + AwsIamUserSecretRotationSchema, + OktaClientSecretRotationSchema ]), z.object({ id: z.string().optional() }) ) diff --git a/frontend/src/components/secret-rotations-v2/forms/schemas/okta-client-secret-rotation-schema.ts b/frontend/src/components/secret-rotations-v2/forms/schemas/okta-client-secret-rotation-schema.ts new file mode 100644 index 000000000..569ee2c6c --- /dev/null +++ b/frontend/src/components/secret-rotations-v2/forms/schemas/okta-client-secret-rotation-schema.ts @@ -0,0 +1,17 @@ +import { z } from "zod"; + +import { BaseSecretRotationSchema } from "@app/components/secret-rotations-v2/forms/schemas/base-secret-rotation-v2-schema"; +import { SecretRotation } from "@app/hooks/api/secretRotationsV2"; + +export const OktaClientSecretRotationSchema = z + .object({ + type: z.literal(SecretRotation.OktaClientSecret), + parameters: z.object({ + clientId: z.string().trim().min(1, "App ID required") + }), + secretsMapping: z.object({ + clientId: z.string().trim().min(1, "Client ID required"), + clientSecret: z.string().trim().min(1, "Client Secret required") + }) + }) + .merge(BaseSecretRotationSchema); diff --git a/frontend/src/components/secret-syncs/forms/SecretSyncDestinationFields/BitbucketSyncFields.tsx b/frontend/src/components/secret-syncs/forms/SecretSyncDestinationFields/BitbucketSyncFields.tsx new file mode 100644 index 000000000..330d75811 --- /dev/null +++ b/frontend/src/components/secret-syncs/forms/SecretSyncDestinationFields/BitbucketSyncFields.tsx @@ -0,0 +1,141 @@ +import { Controller, useFormContext, useWatch } from "react-hook-form"; +import { SingleValue } from "react-select"; + +import { SecretSyncConnectionField } from "@app/components/secret-syncs/forms/SecretSyncConnectionField"; +import { FilterableSelect, FormControl } from "@app/components/v2"; +import { + TBitbucketEnvironment, + TBitbucketRepo, + TBitbucketWorkspace, + useBitbucketConnectionListEnvironments, + useBitbucketConnectionListRepositories, + useBitbucketConnectionListWorkspaces +} from "@app/hooks/api/appConnections/bitbucket"; +import { SecretSync } from "@app/hooks/api/secretSyncs"; + +import { TSecretSyncForm } from "../schemas"; + +export const BitbucketSyncFields = () => { + const { control, setValue } = useFormContext< + TSecretSyncForm & { destination: SecretSync.Bitbucket } + >(); + + const connectionId = useWatch({ name: "connection.id", control }); + const workspace = useWatch({ name: "destinationConfig.workspaceSlug", control }); + const repository = useWatch({ name: "destinationConfig.repositorySlug", control }); + + const { data: workspaces = [], isPending: isWorkspacesLoading } = + useBitbucketConnectionListWorkspaces(connectionId, { + enabled: Boolean(connectionId) + }); + + const { data: repositories = [], isPending: isRepositoriesLoading } = + useBitbucketConnectionListRepositories(connectionId, workspace ?? "", { + enabled: Boolean(connectionId) && Boolean(workspace) + }); + + const { data: environments = [], isPending: isEnvironmentsLoading } = + useBitbucketConnectionListEnvironments(connectionId, workspace ?? "", repository ?? "", { + enabled: Boolean(connectionId) && Boolean(workspace) && Boolean(repository) + }); + + return ( + <> + { + setValue("destinationConfig.workspaceSlug", ""); + setValue("destinationConfig.repositorySlug", ""); + setValue("destinationConfig.environmentId", ""); + }} + /> + + ( + + w.slug === value) ?? null} + onChange={(option) => { + const v = option as SingleValue; + onChange(v?.slug ?? ""); + // Clear downstream selections + setValue("destinationConfig.repositorySlug", ""); + setValue("destinationConfig.environmentId", ""); + }} + options={workspaces} + placeholder="Select workspace..." + getOptionLabel={(option) => option.slug} + getOptionValue={(option) => option.slug} + /> + + )} + /> + + ( + + r.slug === value) ?? null} + onChange={(option) => { + const v = option as SingleValue; + onChange(v?.slug ?? ""); + // Clear downstream selections + setValue("destinationConfig.environmentId", ""); + }} + options={repositories} + placeholder="Select repository..." + getOptionLabel={(option) => option.full_name} + getOptionValue={(option) => option.slug} + /> + + )} + /> + + ( + + e.uuid === value) ?? null} + onChange={(option) => { + const v = option as SingleValue; + onChange(v?.uuid ?? ""); + }} + options={environments} + placeholder="Select environment..." + getOptionLabel={(option) => option.name} + getOptionValue={(option) => option.uuid} + isClearable + /> + + )} + /> + > + ); +}; diff --git a/frontend/src/components/secret-syncs/forms/SecretSyncDestinationFields/SecretSyncDestinationFields.tsx b/frontend/src/components/secret-syncs/forms/SecretSyncDestinationFields/SecretSyncDestinationFields.tsx index 09cf2caec..c933fa44d 100644 --- a/frontend/src/components/secret-syncs/forms/SecretSyncDestinationFields/SecretSyncDestinationFields.tsx +++ b/frontend/src/components/secret-syncs/forms/SecretSyncDestinationFields/SecretSyncDestinationFields.tsx @@ -9,6 +9,7 @@ import { AwsSecretsManagerSyncFields } from "./AwsSecretsManagerSyncFields"; import { AzureAppConfigurationSyncFields } from "./AzureAppConfigurationSyncFields"; import { AzureDevOpsSyncFields } from "./AzureDevOpsSyncFields"; import { AzureKeyVaultSyncFields } from "./AzureKeyVaultSyncFields"; +import { BitbucketSyncFields } from "./BitbucketSyncFields"; import { CamundaSyncFields } from "./CamundaSyncFields"; import { ChecklySyncFields } from "./ChecklySyncFields"; import { CloudflarePagesSyncFields } from "./CloudflarePagesSyncFields"; @@ -91,6 +92,8 @@ export const SecretSyncDestinationFields = () => { return ; case SecretSync.Supabase: return ; + case SecretSync.Bitbucket: + return ; default: throw new Error(`Unhandled Destination Config Field: ${destination}`); } diff --git a/frontend/src/components/secret-syncs/forms/SecretSyncOptionsFields/SecretSyncOptionsFields.tsx b/frontend/src/components/secret-syncs/forms/SecretSyncOptionsFields/SecretSyncOptionsFields.tsx index eaf66a053..e7226eb68 100644 --- a/frontend/src/components/secret-syncs/forms/SecretSyncOptionsFields/SecretSyncOptionsFields.tsx +++ b/frontend/src/components/secret-syncs/forms/SecretSyncOptionsFields/SecretSyncOptionsFields.tsx @@ -63,6 +63,7 @@ export const SecretSyncOptionsFields = ({ hideInitialSync }: Props) => { case SecretSync.Railway: case SecretSync.Checkly: case SecretSync.Supabase: + case SecretSync.Bitbucket: AdditionalSyncOptionsFieldsComponent = null; break; default: diff --git a/frontend/src/components/secret-syncs/forms/SecretSyncReviewFields/BitbucketSyncReviewFields.tsx b/frontend/src/components/secret-syncs/forms/SecretSyncReviewFields/BitbucketSyncReviewFields.tsx new file mode 100644 index 000000000..93630f225 --- /dev/null +++ b/frontend/src/components/secret-syncs/forms/SecretSyncReviewFields/BitbucketSyncReviewFields.tsx @@ -0,0 +1,20 @@ +import { useFormContext } from "react-hook-form"; + +import { TSecretSyncForm } from "@app/components/secret-syncs/forms/schemas"; +import { GenericFieldLabel } from "@app/components/v2"; +import { SecretSync } from "@app/hooks/api/secretSyncs"; + +export const BitbucketSyncReviewFields = () => { + const { watch } = useFormContext(); + const repository = watch("destinationConfig.repositorySlug"); + const environment = watch("destinationConfig.environmentId"); + const workspace = watch("destinationConfig.workspaceSlug"); + + return ( + <> + {repository} + {environment} + {workspace} + > + ); +}; diff --git a/frontend/src/components/secret-syncs/forms/SecretSyncReviewFields/SecretSyncReviewFields.tsx b/frontend/src/components/secret-syncs/forms/SecretSyncReviewFields/SecretSyncReviewFields.tsx index d09f58a2e..d785dc87c 100644 --- a/frontend/src/components/secret-syncs/forms/SecretSyncReviewFields/SecretSyncReviewFields.tsx +++ b/frontend/src/components/secret-syncs/forms/SecretSyncReviewFields/SecretSyncReviewFields.tsx @@ -18,6 +18,7 @@ import { import { AzureAppConfigurationSyncReviewFields } from "./AzureAppConfigurationSyncReviewFields"; import { AzureDevOpsSyncReviewFields } from "./AzureDevOpsSyncReviewFields"; import { AzureKeyVaultSyncReviewFields } from "./AzureKeyVaultSyncReviewFields"; +import { BitbucketSyncReviewFields } from "./BitbucketSyncReviewFields"; import { CamundaSyncReviewFields } from "./CamundaSyncReviewFields"; import { ChecklySyncReviewFields } from "./ChecklySyncReviewFields"; import { CloudflarePagesSyncReviewFields } from "./CloudflarePagesReviewFields"; @@ -144,6 +145,9 @@ export const SecretSyncReviewFields = () => { case SecretSync.Supabase: DestinationFieldsComponent = ; break; + case SecretSync.Bitbucket: + DestinationFieldsComponent = ; + break; default: throw new Error(`Unhandled Destination Review Fields: ${destination}`); } diff --git a/frontend/src/components/secret-syncs/forms/schemas/bitbucket-sync-destination-schema.ts b/frontend/src/components/secret-syncs/forms/schemas/bitbucket-sync-destination-schema.ts new file mode 100644 index 000000000..a10a22d5a --- /dev/null +++ b/frontend/src/components/secret-syncs/forms/schemas/bitbucket-sync-destination-schema.ts @@ -0,0 +1,19 @@ +import { z } from "zod"; + +import { BaseSecretSyncSchema } from "@app/components/secret-syncs/forms/schemas/base-secret-sync-schema"; +import { SecretSync } from "@app/hooks/api/secretSyncs"; + +export const BitbucketSyncDestinationSchema = BaseSecretSyncSchema().merge( + z.object({ + destination: z.literal(SecretSync.Bitbucket), + destinationConfig: z.object({ + repositorySlug: z + .string() + .trim() + .min(1, "Repository slug required") + .describe("Repository slug"), + environmentId: z.string().trim().optional().describe("Deployment environment uuid"), + workspaceSlug: z.string().trim().min(1, "Workspace slug required").describe("Workspace slug") + }) + }) +); diff --git a/frontend/src/components/secret-syncs/forms/schemas/secret-sync-schema.ts b/frontend/src/components/secret-syncs/forms/schemas/secret-sync-schema.ts index 83c334f71..dc082e168 100644 --- a/frontend/src/components/secret-syncs/forms/schemas/secret-sync-schema.ts +++ b/frontend/src/components/secret-syncs/forms/schemas/secret-sync-schema.ts @@ -6,6 +6,7 @@ import { AwsSecretsManagerSyncDestinationSchema } from "./aws-secrets-manager-sy import { AzureAppConfigurationSyncDestinationSchema } from "./azure-app-configuration-sync-destination-schema"; import { AzureDevOpsSyncDestinationSchema } from "./azure-devops-sync-destination-schema"; import { AzureKeyVaultSyncDestinationSchema } from "./azure-key-vault-sync-destination-schema"; +import { BitbucketSyncDestinationSchema } from "./bitbucket-sync-destination-schema"; import { CamundaSyncDestinationSchema } from "./camunda-sync-destination-schema"; import { ChecklySyncDestinationSchema } from "./checkly-sync-destination-schema"; import { CloudflarePagesSyncDestinationSchema } from "./cloudflare-pages-sync-destination-schema"; @@ -55,7 +56,8 @@ const SecretSyncUnionSchema = z.discriminatedUnion("destination", [ SupabaseSyncDestinationSchema, ZabbixSyncDestinationSchema, RailwaySyncDestinationSchema, - ChecklySyncDestinationSchema + ChecklySyncDestinationSchema, + BitbucketSyncDestinationSchema ]); export const SecretSyncFormSchema = SecretSyncUnionSchema; diff --git a/frontend/src/components/v2/CopyButton/CopyButton.tsx b/frontend/src/components/v2/CopyButton/CopyButton.tsx index ff1161ca9..135dec366 100644 --- a/frontend/src/components/v2/CopyButton/CopyButton.tsx +++ b/frontend/src/components/v2/CopyButton/CopyButton.tsx @@ -41,7 +41,8 @@ export const CopyButton = ({ variant={variant} className={twMerge("group relative", color)} size={size} - onClick={() => { + onClick={(e) => { + e.stopPropagation(); handleCopyText(); }} > diff --git a/frontend/src/components/v2/DatePicker/DatePicker.tsx b/frontend/src/components/v2/DatePicker/DatePicker.tsx index 028d6623a..115b0ad3e 100644 --- a/frontend/src/components/v2/DatePicker/DatePicker.tsx +++ b/frontend/src/components/v2/DatePicker/DatePicker.tsx @@ -1,11 +1,13 @@ import { ChangeEventHandler, useState } from "react"; -import { DayPicker, DayPickerProps, getDefaultClassNames, UI } from "react-day-picker"; +import { DayPicker, DayPickerProps, getDefaultClassNames, TZDate, UI } from "react-day-picker"; import { faCalendar } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { PopoverContentProps, PopoverProps } from "@radix-ui/react-popover"; import { format, setHours, setMinutes } from "date-fns"; import { twMerge } from "tailwind-merge"; +import { formatDateTime, Timezone } from "@app/helpers/datetime"; + import { Button } from "../Button"; import { Input } from "../Input"; import { Popover, PopoverContent, PopoverTrigger } from "../Popoverv2"; @@ -19,6 +21,32 @@ export type DatePickerProps = Omit & { popUpContentProps: PopoverContentProps; dateFormat?: "PPP" | "PP" | "P"; // extend as needed hideTime?: boolean; + buttonClassName?: string; + timezone?: Timezone; +}; + +const localTimeToUTC = (timeString: string) => { + const today = new Date(); + const [hours, minutes] = timeString.split(":").map(Number); + + today.setHours(hours, minutes, 0, 0); + + const utcHours = today.getUTCHours().toString().padStart(2, "0"); + const utcMinutes = today.getUTCMinutes().toString().padStart(2, "0"); + + return `${utcHours}:${utcMinutes}`; +}; + +const utcTimeToLocal = (utcTimeString: string) => { + const today = new Date(); + const [hours, minutes] = utcTimeString.split(":").map(Number); + + today.setUTCHours(hours, minutes, 0, 0); + + const localHours = today.getHours().toString().padStart(2, "0"); + const localMinutes = today.getMinutes().toString().padStart(2, "0"); + + return `${localHours}:${localMinutes}`; }; // Doc: https://react-day-picker.js.org/ @@ -29,12 +57,16 @@ export const DatePicker = ({ popUpContentProps, dateFormat = "PPP", hideTime = false, + buttonClassName, + timezone, ...props }: DatePickerProps) => { const [timeValue, setTimeValue] = useState(value ? format(value, "HH:mm") : "00:00"); + const displayUtc = timezone === Timezone.UTC; const handleTimeChange: ChangeEventHandler = (e) => { - const time = e.target.value; + const time = displayUtc ? utcTimeToLocal(e.target.value) : e.target.value; + if (time) { setTimeValue(time); if (value) { @@ -59,8 +91,14 @@ export const DatePicker = ({ return ( - }> - {value ? format(value, dateFormat) : "Pick a date and time"} + } + > + {value + ? formatDateTime({ timestamp: value, timezone, dateFormat }) + : "Pick a date and time"} handleDaySelect(date ? new TZDate(date, undefined) : undefined)} className="font-inter text-mineshaft-200" + timeZone={displayUtc ? "UTC" : undefined} classNames={{ today: "text-primary border-primary", selected: " text-mineshaft-100 bg-mineshaft-500", @@ -91,7 +130,7 @@ export const DatePicker = ({ diff --git a/frontend/src/components/v2/Select/Select.tsx b/frontend/src/components/v2/Select/Select.tsx index 91c376662..f114c0f02 100644 --- a/frontend/src/components/v2/Select/Select.tsx +++ b/frontend/src/components/v2/Select/Select.tsx @@ -19,6 +19,7 @@ type Props = { icon?: IconProp; isMulti?: boolean; iconClassName?: string; + dropdownContainerStyle?: React.CSSProperties; }; export type SelectProps = Omit & Props; @@ -35,6 +36,7 @@ export const Select = forwardRef( position, containerClassName, iconClassName, + dropdownContainerStyle, ...props }, ref @@ -82,7 +84,7 @@ export const Select = forwardRef( dropdownContainerClassName )} position={position} - style={{ width: "var(--radix-select-trigger-width)" }} + style={dropdownContainerStyle ?? { width: "var(--radix-select-trigger-width)" }} > diff --git a/frontend/src/const/routes.ts b/frontend/src/const/routes.ts index a90699087..47c7c3d24 100644 --- a/frontend/src/const/routes.ts +++ b/frontend/src/const/routes.ts @@ -70,276 +70,276 @@ export const ROUTE_PATHS = Object.freeze({ }, SecretManager: { ApprovalPage: setRoute( - "/projects/$projectId/secret-manager/approval", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/approval" + "/projects/secret-management/$projectId/approval", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/approval" ), SecretDashboardPage: setRoute( - "/projects/$projectId/secret-manager/secrets/$envSlug", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/secrets/$envSlug" + "/projects/secret-management/$projectId/secrets/$envSlug", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/secrets/$envSlug" ), RollbackPreviewPage: setRoute( - "/projects/$projectId/secret-manager/commits/$environment/$folderId/$commitId/restore", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/$commitId/restore" + "/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId/restore", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/restore" ), CommitDetailsPage: setRoute( - "/projects/$projectId/secret-manager/commits/$environment/$folderId/$commitId", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/$commitId" + "/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId" ), CommitsPage: setRoute( - "/projects/$projectId/secret-manager/commits/$environment/$folderId", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId" + "/projects/secret-management/$projectId/commits/$environment/$folderId", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId" ), OverviewPage: setRoute( - "/projects/$projectId/secret-manager/overview", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/overview" + "/projects/secret-management/$projectId/overview", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/overview" ), IntegrationsListPage: setRoute( - "/projects/$projectId/secret-manager/integrations", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/" + "/projects/secret-management/$projectId/integrations", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/" ), IntegrationDetailsByIDPage: setRoute( - "/projects/$projectId/secret-manager/integrations/$integrationId", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/$integrationId" + "/projects/secret-management/$projectId/integrations/$integrationId", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/$integrationId" ), SecretSyncDetailsByIDPage: setRoute( - "/projects/$projectId/secret-manager/integrations/secret-syncs/$destination/$syncId", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/secret-syncs/$destination/$syncId" + "/projects/secret-management/$projectId/integrations/secret-syncs/$destination/$syncId", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/secret-syncs/$destination/$syncId" ), Integratons: { SelectIntegrationAuth: setRoute( - "/projects/$projectId/secret-manager/integrations/select-integration-auth", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/select-integration-auth" + "/projects/secret-management/$projectId/integrations/select-integration-auth", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/select-integration-auth" ), HerokuOauthCallbackPage: setRoute( - "/projects/$projectId/secret-manager/integrations/heroku/oauth2/callback", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/heroku/oauth2/callback" + "/projects/secret-management/$projectId/integrations/heroku/oauth2/callback", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/oauth2/callback" ), HerokuConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/heroku/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/heroku/create" + "/projects/secret-management/$projectId/integrations/heroku/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/create" ), AwsParameterStoreConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/aws-parameter-store/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-parameter-store/create" + "/projects/secret-management/$projectId/integrations/aws-parameter-store/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/create" ), AwsSecretManagerConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/aws-secret-manager/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-secret-manager/create" + "/projects/secret-management/$projectId/integrations/aws-secret-manager/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/create" ), AzureAppConfigurationsOauthCallbackPage: setRoute( - "/projects/$projectId/secret-manager/integrations/azure-app-configuration/oauth2/callback", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-app-configuration/oauth2/callback" + "/projects/secret-management/$projectId/integrations/azure-app-configuration/oauth2/callback", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/oauth2/callback" ), AzureAppConfigurationsConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/azure-app-configuration/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-app-configuration/create" + "/projects/secret-management/$projectId/integrations/azure-app-configuration/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/create" ), AzureDevopsConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/azure-devops/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-devops/create" + "/projects/secret-management/$projectId/integrations/azure-devops/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/create" ), AzureKeyVaultAuthorizePage: setRoute( - "/projects/$projectId/secret-manager/integrations/azure-key-vault/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-key-vault/authorize" + "/projects/secret-management/$projectId/integrations/azure-key-vault/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/authorize" ), AzureKeyVaultOauthCallbackPage: setRoute( - "/projects/$projectId/secret-manager/integrations/azure-key-vault/oauth2/callback", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-key-vault/oauth2/callback" + "/projects/secret-management/$projectId/integrations/azure-key-vault/oauth2/callback", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/oauth2/callback" ), AzureKeyVaultConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/azure-key-vault/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-key-vault/create" + "/projects/secret-management/$projectId/integrations/azure-key-vault/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/create" ), BitbucketOauthCallbackPage: setRoute( - "/projects/$projectId/secret-manager/integrations/bitbucket/oauth2/callback", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/bitbucket/oauth2/callback" + "/projects/secret-management/$projectId/integrations/bitbucket/oauth2/callback", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/oauth2/callback" ), BitbucketConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/bitbucket/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/bitbucket/create" + "/projects/secret-management/$projectId/integrations/bitbucket/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/create" ), ChecklyConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/checkly/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/checkly/create" + "/projects/secret-management/$projectId/integrations/checkly/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/create" ), CircleConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/circleci/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/circleci/create" + "/projects/secret-management/$projectId/integrations/circleci/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/create" ), CloudflarePagesConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/cloudflare-pages/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-pages/create" + "/projects/secret-management/$projectId/integrations/cloudflare-pages/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/create" ), DigitalOceanAppPlatformConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/digital-ocean-app-platform/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/digital-ocean-app-platform/create" + "/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/create" ), CloudflareWorkersConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/cloudflare-workers/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-workers/create" + "/projects/secret-management/$projectId/integrations/cloudflare-workers/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/create" ), CodefreshConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/codefresh/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/codefresh/create" + "/projects/secret-management/$projectId/integrations/codefresh/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/create" ), GcpSecretManagerConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/gcp-secret-manager/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gcp-secret-manager/create" + "/projects/secret-management/$projectId/integrations/gcp-secret-manager/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/create" ), GcpSecretManagerOauthCallbackPage: setRoute( - "/projects/$projectId/secret-manager/integrations/gcp-secret-manager/oauth2/callback", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gcp-secret-manager/oauth2/callback" + "/projects/secret-management/$projectId/integrations/gcp-secret-manager/oauth2/callback", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/oauth2/callback" ), GithubConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/github/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/github/create" + "/projects/secret-management/$projectId/integrations/github/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/create" ), GithubOauthCallbackPage: setRoute( - "/projects/$projectId/secret-manager/integrations/github/oauth2/callback", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/github/oauth2/callback" + "/projects/secret-management/$projectId/integrations/github/oauth2/callback", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/oauth2/callback" ), GitlabConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/gitlab/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gitlab/create" + "/projects/secret-management/$projectId/integrations/gitlab/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/create" ), GitlabOauthCallbackPage: setRoute( - "/projects/$projectId/secret-manager/integrations/gitlab/oauth2/callback", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gitlab/oauth2/callback" + "/projects/secret-management/$projectId/integrations/gitlab/oauth2/callback", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/oauth2/callback" ), VercelOauthCallbackPage: setRoute( - "/projects/$projectId/secret-manager/integrations/vercel/oauth2/callback", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/vercel/oauth2/callback" + "/projects/secret-management/$projectId/integrations/vercel/oauth2/callback", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/oauth2/callback" ), VercelConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/vercel/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/vercel/create" + "/projects/secret-management/$projectId/integrations/vercel/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/create" ), FlyioConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/flyio/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/flyio/create" + "/projects/secret-management/$projectId/integrations/flyio/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/create" ), HashicorpVaultConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/hashicorp-vault/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hashicorp-vault/create" + "/projects/secret-management/$projectId/integrations/hashicorp-vault/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/create" ), HasuraCloudConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/hasura-cloud/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hasura-cloud/create" + "/projects/secret-management/$projectId/integrations/hasura-cloud/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/create" ), LaravelForgeConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/laravel-forge/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/laravel-forge/create" + "/projects/secret-management/$projectId/integrations/laravel-forge/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/create" ), NorthflankConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/northflank/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/northflank/create" + "/projects/secret-management/$projectId/integrations/northflank/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/create" ), RailwayConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/railway/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/railway/create" + "/projects/secret-management/$projectId/integrations/railway/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/create" ), RenderConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/render/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/render/create" + "/projects/secret-management/$projectId/integrations/render/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/create" ), RundeckConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/rundeck/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/rundeck/create" + "/projects/secret-management/$projectId/integrations/rundeck/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/create" ), WindmillConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/windmill/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/windmill/create" + "/projects/secret-management/$projectId/integrations/windmill/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/create" ), TravisCIConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/travisci/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/travisci/create" + "/projects/secret-management/$projectId/integrations/travisci/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/create" ), TerraformCloudConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/terraform-cloud/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/terraform-cloud/create" + "/projects/secret-management/$projectId/integrations/terraform-cloud/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/create" ), TeamcityConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/teamcity/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/teamcity/create" + "/projects/secret-management/$projectId/integrations/teamcity/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/create" ), SupabaseConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/supabase/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/supabase/create" + "/projects/secret-management/$projectId/integrations/supabase/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/create" ), OctopusDeployCloudConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/octopus-deploy/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/octopus-deploy/create" + "/projects/secret-management/$projectId/integrations/octopus-deploy/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/create" ), DatabricksConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/databricks/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/databricks/create" + "/projects/secret-management/$projectId/integrations/databricks/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/create" ), QoveryConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/qovery/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/qovery/create" + "/projects/secret-management/$projectId/integrations/qovery/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/create" ), Cloud66ConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/cloud-66/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloud-66/create" + "/projects/secret-management/$projectId/integrations/cloud-66/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/create" ), NetlifyConfigurePage: setRoute( - "/projects/$projectId/secret-manager/integrations/netlify/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/netlify/create" + "/projects/secret-management/$projectId/integrations/netlify/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/create" ), NetlifyOuathCallbackPage: setRoute( - "/projects/$projectId/secret-manager/integrations/netlify/oauth2/callback", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/netlify/oauth2/callback" + "/projects/secret-management/$projectId/integrations/netlify/oauth2/callback", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/oauth2/callback" ) } }, CertManager: { CertAuthDetailsByIDPage: setRoute( - "/projects/$projectId/cert-manager/ca/$caName", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/ca/$caName" + "/projects/cert-management/$projectId/ca/$caName", + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/ca/$caName" ), SubscribersPage: setRoute( - "/projects/$projectId/cert-manager/subscribers", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/subscribers" + "/projects/cert-management/$projectId/subscribers", + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/subscribers" ), CertificatesPage: setRoute( - "/projects/$projectId/cert-manager/certificates", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificates" + "/projects/cert-management/$projectId/certificates", + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificates" ), CertificateAuthoritiesPage: setRoute( - "/projects/$projectId/cert-manager/certificate-authorities", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificate-authorities" + "/projects/cert-management/$projectId/certificate-authorities", + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificate-authorities" ), AlertingPage: setRoute( - "/projects/$projectId/cert-manager/alerting", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/alerting" + "/projects/cert-management/$projectId/alerting", + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/alerting" ), PkiCollectionDetailsByIDPage: setRoute( - "/projects/$projectId/cert-manager/pki-collections/$collectionId", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/pki-collections/$collectionId" + "/projects/cert-management/$projectId/pki-collections/$collectionId", + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/pki-collections/$collectionId" ), PkiSubscriberDetailsByIDPage: setRoute( - "/projects/$projectId/cert-manager/subscribers/$subscriberName", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/subscribers/$subscriberName" + "/projects/cert-management/$projectId/subscribers/$subscriberName", + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/subscribers/$subscriberName" ) }, Ssh: { SshCaByIDPage: setRoute( - "/projects/$projectId/ssh/ca/$caId", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/ca/$caId" + "/projects/ssh/$projectId/ca/$caId", + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/ca/$caId" ), SshHostGroupDetailsByIDPage: setRoute( - "/projects/$projectId/ssh/ssh-host-groups/$sshHostGroupId", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/ssh-host-groups/$sshHostGroupId" + "/projects/ssh/$projectId/ssh-host-groups/$sshHostGroupId", + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/ssh-host-groups/$sshHostGroupId" ) }, SecretScanning: { DataSourceByIdPage: setRoute( - "/projects/$projectId/secret-scanning/data-sources/$type/$dataSourceId", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/data-sources/$type/$dataSourceId" + "/projects/secret-scanning/$projectId/data-sources/$type/$dataSourceId", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/$type/$dataSourceId" ), FindingsPage: setRoute( - "/projects/$projectId/secret-scanning/findings", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/findings" + "/projects/secret-scanning/$projectId/findings", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/findings" ) }, Public: { diff --git a/frontend/src/helpers/appConnections.ts b/frontend/src/helpers/appConnections.ts index 996483904..807569c6e 100644 --- a/frontend/src/helpers/appConnections.ts +++ b/frontend/src/helpers/appConnections.ts @@ -17,7 +17,9 @@ import { AzureClientSecretsConnectionMethod, AzureDevOpsConnectionMethod, AzureKeyVaultConnectionMethod, + BitbucketConnectionMethod, CamundaConnectionMethod, + ChecklyConnectionMethod, CloudflareConnectionMethod, DatabricksConnectionMethod, FlyioConnectionMethod, @@ -26,13 +28,19 @@ import { GitHubRadarConnectionMethod, GitLabConnectionMethod, HCVaultConnectionMethod, + HerokuConnectionMethod, HumanitecConnectionMethod, LdapConnectionMethod, MsSqlConnectionMethod, MySqlConnectionMethod, + OCIConnectionMethod, + OktaConnectionMethod, OnePassConnectionMethod, OracleDBConnectionMethod, PostgresConnectionMethod, + RailwayConnectionMethod, + RenderConnectionMethod, + SupabaseConnectionMethod, TAppConnection, TeamCityConnectionMethod, TerraformCloudConnectionMethod, @@ -40,13 +48,6 @@ import { WindmillConnectionMethod, ZabbixConnectionMethod } from "@app/hooks/api/appConnections/types"; -import { BitbucketConnectionMethod } from "@app/hooks/api/appConnections/types/bitbucket-connection"; -import { ChecklyConnectionMethod } from "@app/hooks/api/appConnections/types/checkly-connection"; -import { HerokuConnectionMethod } from "@app/hooks/api/appConnections/types/heroku-connection"; -import { OCIConnectionMethod } from "@app/hooks/api/appConnections/types/oci-connection"; -import { RailwayConnectionMethod } from "@app/hooks/api/appConnections/types/railway-connection"; -import { RenderConnectionMethod } from "@app/hooks/api/appConnections/types/render-connection"; -import { SupabaseConnectionMethod } from "@app/hooks/api/appConnections/types/supabase-connection"; export const APP_CONNECTION_MAP: Record< AppConnection, @@ -98,7 +99,8 @@ export const APP_CONNECTION_MAP: Record< [AppConnection.Railway]: { name: "Railway", image: "Railway.png" }, [AppConnection.Bitbucket]: { name: "Bitbucket", image: "Bitbucket.png" }, [AppConnection.Checkly]: { name: "Checkly", image: "Checkly.png" }, - [AppConnection.Supabase]: { name: "Supabase", image: "Supabase.png" } + [AppConnection.Supabase]: { name: "Supabase", image: "Supabase.png" }, + [AppConnection.Okta]: { name: "Okta", image: "Okta.png" } }; export const getAppConnectionMethodDetails = (method: TAppConnection["method"]) => { @@ -132,6 +134,7 @@ export const getAppConnectionMethodDetails = (method: TAppConnection["method"]) case CloudflareConnectionMethod.ApiToken: case BitbucketConnectionMethod.ApiToken: case ZabbixConnectionMethod.ApiToken: + case OktaConnectionMethod.ApiToken: return { name: "API Token", icon: faKey }; case PostgresConnectionMethod.UsernameAndPassword: case MsSqlConnectionMethod.UsernameAndPassword: diff --git a/frontend/src/helpers/datetime.ts b/frontend/src/helpers/datetime.ts new file mode 100644 index 000000000..6e0fb8e48 --- /dev/null +++ b/frontend/src/helpers/datetime.ts @@ -0,0 +1,24 @@ +import { format } from "date-fns"; + +export enum Timezone { + Local = "local", + UTC = "UTC" +} + +export const formatDateTime = ({ + timezone, + timestamp, + dateFormat = "MMM do yyyy, hh:mm a" +}: { + timestamp: string | Date; + timezone?: Timezone; + dateFormat?: string; +}) => { + const date = new Date(timestamp); + + if (timezone === Timezone.UTC) { + const utcDate = new Date(date.getTime() + date.getTimezoneOffset() * 60000); + return `${format(utcDate, dateFormat)}`; + } + return format(date, dateFormat); +}; diff --git a/frontend/src/helpers/project.ts b/frontend/src/helpers/project.ts index e75bb63de..3b04b263d 100644 --- a/frontend/src/helpers/project.ts +++ b/frontend/src/helpers/project.ts @@ -42,7 +42,8 @@ export const initProjectHelper = async ({ projectName }: { projectName: string } const { data: { project } } = await createWorkspace({ - projectName + projectName, + type: ProjectType.SecretManager }); try { @@ -59,20 +60,34 @@ export const initProjectHelper = async ({ projectName }: { projectName: string } return project; }; + +export const getProjectBaseURL = (type: ProjectType) => { + switch (type) { + case ProjectType.SecretManager: + return "/projects/secret-management/$projectId"; + case ProjectType.CertificateManager: + return "/projects/cert-management/$projectId"; + default: + return `/projects/${type}/$projectId` as const; + } +}; + export const getProjectHomePage = (type: ProjectType) => { switch (type) { + case ProjectType.SecretManager: + return "/projects/secret-management/$projectId/overview"; case ProjectType.CertificateManager: - return `/projects/$projectId/${type}/subscribers` as const; + return "/projects/cert-management/$projectId/subscribers"; case ProjectType.SecretScanning: - return `/projects/$projectId/${type}/data-sources` as const; + return `/projects/${type}/$projectId/data-sources` as const; default: - return `/projects/$projectId/${type}/overview` as const; + return `/projects/${type}/$projectId/overview` as const; } }; export const getProjectTitle = (type: ProjectType) => { const titleConvert = { - [ProjectType.SecretManager]: "Secret Management", + [ProjectType.SecretManager]: "Secrets Management", [ProjectType.KMS]: "Key Management", [ProjectType.CertificateManager]: "Cert Management", [ProjectType.SSH]: "SSH", @@ -81,7 +96,13 @@ export const getProjectTitle = (type: ProjectType) => { return titleConvert[type]; }; -export const getCurrentProductFromUrl = (location: string) => { - const type = Object.values(ProjectType).find((el) => location.includes(`/${el}`)); - return type; +export const getProjectLottieIcon = (type: ProjectType) => { + const titleConvert = { + [ProjectType.SecretManager]: "vault", + [ProjectType.KMS]: "unlock", + [ProjectType.CertificateManager]: "note", + [ProjectType.SSH]: "terminal", + [ProjectType.SecretScanning]: "secret-scan" + }; + return titleConvert[type]; }; diff --git a/frontend/src/helpers/secretRotationsV2.ts b/frontend/src/helpers/secretRotationsV2.ts index 6e484881d..2979a7623 100644 --- a/frontend/src/helpers/secretRotationsV2.ts +++ b/frontend/src/helpers/secretRotationsV2.ts @@ -44,6 +44,11 @@ export const SECRET_ROTATION_MAP: Record< name: "AWS IAM User Secret", image: "Amazon Web Services.png", size: 50 + }, + [SecretRotation.OktaClientSecret]: { + name: "Okta Client Secret", + image: "Okta.png", + size: 50 } }; @@ -55,7 +60,8 @@ export const SECRET_ROTATION_CONNECTION_MAP: Record = { [SecretRotation.Auth0ClientSecret]: false, [SecretRotation.AzureClientSecret]: true, [SecretRotation.LdapPassword]: false, - [SecretRotation.AwsIamUserSecret]: true + [SecretRotation.AwsIamUserSecret]: true, + [SecretRotation.OktaClientSecret]: true }; export const getRotateAtLocal = ({ hours, minutes }: TSecretRotationV2["rotateAtUtc"]) => { diff --git a/frontend/src/helpers/secretSyncs.ts b/frontend/src/helpers/secretSyncs.ts index 29b4f2f73..cabd7fa6e 100644 --- a/frontend/src/helpers/secretSyncs.ts +++ b/frontend/src/helpers/secretSyncs.ts @@ -101,6 +101,10 @@ export const SECRET_SYNC_MAP: Record = { [SecretSync.Supabase]: AppConnection.Supabase, [SecretSync.Zabbix]: AppConnection.Zabbix, [SecretSync.Railway]: AppConnection.Railway, - [SecretSync.Checkly]: AppConnection.Checkly + [SecretSync.Checkly]: AppConnection.Checkly, + [SecretSync.Bitbucket]: AppConnection.Bitbucket }; export const SECRET_SYNC_INITIAL_SYNC_BEHAVIOR_MAP: Record< diff --git a/frontend/src/hooks/api/appConnections/bitbucket/queries.tsx b/frontend/src/hooks/api/appConnections/bitbucket/queries.tsx index bfae0534f..d4f85bcf7 100644 --- a/frontend/src/hooks/api/appConnections/bitbucket/queries.tsx +++ b/frontend/src/hooks/api/appConnections/bitbucket/queries.tsx @@ -4,8 +4,10 @@ import { apiRequest } from "@app/config/request"; import { appConnectionKeys } from "../queries"; import { + TBitbucketConnectionListEnvironmentsResponse, TBitbucketConnectionListRepositoriesResponse, TBitbucketConnectionListWorkspacesResponse, + TBitbucketEnvironment, TBitbucketRepo, TBitbucketWorkspace } from "./types"; @@ -15,7 +17,9 @@ const bitbucketConnectionKeys = { listRepos: (connectionId: string, workspaceSlug: string) => [...bitbucketConnectionKeys.all, "repos", connectionId, workspaceSlug] as const, listWorkspaces: (connectionId: string) => - [...bitbucketConnectionKeys.all, "workspaces", connectionId] as const + [...bitbucketConnectionKeys.all, "workspaces", connectionId] as const, + listEnvironments: (connectionId: string, workspaceSlug: string, repoSlug: string) => + [...bitbucketConnectionKeys.all, "environments", connectionId, workspaceSlug, repoSlug] as const }; export const useBitbucketConnectionListWorkspaces = ( @@ -68,3 +72,30 @@ export const useBitbucketConnectionListRepositories = ( ...options }); }; + +export const useBitbucketConnectionListEnvironments = ( + connectionId: string, + workspaceSlug: string, + repoSlug: string, + options?: Omit< + UseQueryOptions< + TBitbucketEnvironment[], + unknown, + TBitbucketEnvironment[], + ReturnType + >, + "queryKey" | "queryFn" + > +) => { + return useQuery({ + queryKey: bitbucketConnectionKeys.listEnvironments(connectionId, workspaceSlug, repoSlug), + queryFn: async () => { + const { data } = await apiRequest.get( + `/api/v1/app-connections/bitbucket/${connectionId}/environments?workspaceSlug=${encodeURIComponent(workspaceSlug)}&repositorySlug=${encodeURIComponent(repoSlug)}` + ); + + return data.environments; + }, + ...options + }); +}; diff --git a/frontend/src/hooks/api/appConnections/bitbucket/types.ts b/frontend/src/hooks/api/appConnections/bitbucket/types.ts index e7e653a93..79ebbc7cc 100644 --- a/frontend/src/hooks/api/appConnections/bitbucket/types.ts +++ b/frontend/src/hooks/api/appConnections/bitbucket/types.ts @@ -15,3 +15,13 @@ export type TBitbucketConnectionListWorkspacesResponse = { export type TBitbucketConnectionListRepositoriesResponse = { repositories: TBitbucketRepo[]; }; + +export type TBitbucketEnvironment = { + uuid: string; + name: string; + slug: string; +}; + +export type TBitbucketConnectionListEnvironmentsResponse = { + environments: TBitbucketEnvironment[]; +}; diff --git a/frontend/src/hooks/api/appConnections/enums.ts b/frontend/src/hooks/api/appConnections/enums.ts index 965675bc7..2e1e59655 100644 --- a/frontend/src/hooks/api/appConnections/enums.ts +++ b/frontend/src/hooks/api/appConnections/enums.ts @@ -32,5 +32,6 @@ export enum AppConnection { Zabbix = "zabbix", Railway = "railway", Checkly = "checkly", - Supabase = "supabase" + Supabase = "supabase", + Okta = "okta" } diff --git a/frontend/src/hooks/api/appConnections/okta/index.ts b/frontend/src/hooks/api/appConnections/okta/index.ts new file mode 100644 index 000000000..2c1906d36 --- /dev/null +++ b/frontend/src/hooks/api/appConnections/okta/index.ts @@ -0,0 +1,2 @@ +export * from "./queries"; +export * from "./types"; diff --git a/frontend/src/hooks/api/appConnections/okta/queries.tsx b/frontend/src/hooks/api/appConnections/okta/queries.tsx new file mode 100644 index 000000000..9823a296a --- /dev/null +++ b/frontend/src/hooks/api/appConnections/okta/queries.tsx @@ -0,0 +1,36 @@ +import { useQuery, UseQueryOptions } from "@tanstack/react-query"; + +import { apiRequest } from "@app/config/request"; + +import { appConnectionKeys } from "../queries"; +import { TOktaApp } from "./types"; + +const oktaConnectionKeys = { + all: [...appConnectionKeys.all, "okta"] as const, + listApps: (connectionId: string) => [...oktaConnectionKeys.all, "apps", connectionId] as const +}; + +export const useOktaConnectionListApps = ( + connectionId: string, + options?: Omit< + UseQueryOptions< + TOktaApp[], + unknown, + TOktaApp[], + ReturnType + >, + "queryKey" | "queryFn" + > +) => { + return useQuery({ + queryKey: oktaConnectionKeys.listApps(connectionId), + queryFn: async () => { + const { data } = await apiRequest.get<{ apps: TOktaApp[] }>( + `/api/v1/app-connections/okta/${connectionId}/apps` + ); + + return data.apps; + }, + ...options + }); +}; diff --git a/frontend/src/hooks/api/appConnections/okta/types.ts b/frontend/src/hooks/api/appConnections/okta/types.ts new file mode 100644 index 000000000..8acc6c04d --- /dev/null +++ b/frontend/src/hooks/api/appConnections/okta/types.ts @@ -0,0 +1,4 @@ +export type TOktaApp = { + id: string; + label: string; +}; diff --git a/frontend/src/hooks/api/appConnections/types/app-options.ts b/frontend/src/hooks/api/appConnections/types/app-options.ts index b6b00a615..e9bc5b243 100644 --- a/frontend/src/hooks/api/appConnections/types/app-options.ts +++ b/frontend/src/hooks/api/appConnections/types/app-options.ts @@ -152,6 +152,10 @@ export type TSupabaseConnectionOption = TAppConnectionOptionBase & { app: AppConnection.Supabase; }; +export type TOktaConnectionOption = TAppConnectionOptionBase & { + app: AppConnection.Okta; +}; + export type TAppConnectionOption = | TAwsConnectionOption | TGitHubConnectionOption @@ -183,7 +187,8 @@ export type TAppConnectionOption = | TBitbucketConnectionOption | TZabbixConnectionOption | TRailwayConnectionOption - | TChecklyConnectionOption; + | TChecklyConnectionOption + | TOktaConnectionOption; export type TAppConnectionOptionMap = { [AppConnection.AWS]: TAwsConnectionOption; @@ -220,4 +225,5 @@ export type TAppConnectionOptionMap = { [AppConnection.Railway]: TRailwayConnectionOption; [AppConnection.Checkly]: TChecklyConnectionOption; [AppConnection.Supabase]: TSupabaseConnectionOption; + [AppConnection.Okta]: TOktaConnectionOption; }; diff --git a/frontend/src/hooks/api/appConnections/types/index.ts b/frontend/src/hooks/api/appConnections/types/index.ts index e177fa2ab..5085feab3 100644 --- a/frontend/src/hooks/api/appConnections/types/index.ts +++ b/frontend/src/hooks/api/appConnections/types/index.ts @@ -24,6 +24,7 @@ import { TLdapConnection } from "./ldap-connection"; import { TMsSqlConnection } from "./mssql-connection"; import { TMySqlConnection } from "./mysql-connection"; import { TOCIConnection } from "./oci-connection"; +import { TOktaConnection } from "./okta-connection"; import { TOracleDBConnection } from "./oracledb-connection"; import { TPostgresConnection } from "./postgres-connection"; import { TRailwayConnection } from "./railway-connection"; @@ -44,6 +45,7 @@ export * from "./azure-devops-connection"; export * from "./azure-key-vault-connection"; export * from "./bitbucket-connection"; export * from "./camunda-connection"; +export * from "./checkly-connection"; export * from "./cloudflare-connection"; export * from "./databricks-connection"; export * from "./flyio-connection"; @@ -58,9 +60,12 @@ export * from "./ldap-connection"; export * from "./mssql-connection"; export * from "./mysql-connection"; export * from "./oci-connection"; +export * from "./okta-connection"; export * from "./oracledb-connection"; export * from "./postgres-connection"; +export * from "./railway-connection"; export * from "./render-connection"; +export * from "./supabase-connection"; export * from "./teamcity-connection"; export * from "./terraform-cloud-connection"; export * from "./vercel-connection"; @@ -101,7 +106,8 @@ export type TAppConnection = | TZabbixConnection | TRailwayConnection | TChecklyConnection - | TSupabaseConnection; + | TSupabaseConnection + | TOktaConnection; export type TAvailableAppConnection = Pick; @@ -113,11 +119,20 @@ export type TAvailableAppConnectionsResponse = { appConnections: TAvailableAppCo export type TCreateAppConnectionDTO = Pick< TAppConnection, - "name" | "credentials" | "method" | "app" | "description" | "isPlatformManagedCredentials" + | "name" + | "credentials" + | "method" + | "app" + | "description" + | "isPlatformManagedCredentials" + | "gatewayId" >; export type TUpdateAppConnectionDTO = Partial< - Pick + Pick< + TAppConnection, + "name" | "credentials" | "description" | "isPlatformManagedCredentials" | "gatewayId" + > > & { connectionId: string; app: AppConnection; @@ -163,4 +178,5 @@ export type TAppConnectionMap = { [AppConnection.Railway]: TRailwayConnection; [AppConnection.Checkly]: TChecklyConnection; [AppConnection.Supabase]: TSupabaseConnection; + [AppConnection.Okta]: TOktaConnection; }; diff --git a/frontend/src/hooks/api/appConnections/types/okta-connection.ts b/frontend/src/hooks/api/appConnections/types/okta-connection.ts new file mode 100644 index 000000000..a622388b4 --- /dev/null +++ b/frontend/src/hooks/api/appConnections/types/okta-connection.ts @@ -0,0 +1,14 @@ +import { AppConnection } from "@app/hooks/api/appConnections/enums"; +import { TRootAppConnection } from "@app/hooks/api/appConnections/types/root-connection"; + +export enum OktaConnectionMethod { + ApiToken = "api-token" +} + +export type TOktaConnection = TRootAppConnection & { app: AppConnection.Okta } & { + method: OktaConnectionMethod.ApiToken; + credentials: { + instanceUrl: string; + apiToken: string; + }; +}; diff --git a/frontend/src/hooks/api/appConnections/types/root-connection.ts b/frontend/src/hooks/api/appConnections/types/root-connection.ts index 52571d067..5b8f5cd02 100644 --- a/frontend/src/hooks/api/appConnections/types/root-connection.ts +++ b/frontend/src/hooks/api/appConnections/types/root-connection.ts @@ -7,4 +7,5 @@ export type TRootAppConnection = { createdAt: string; updatedAt: string; isPlatformManagedCredentials?: boolean; + gatewayId?: string | null; }; diff --git a/frontend/src/hooks/api/auditLogs/queries.tsx b/frontend/src/hooks/api/auditLogs/queries.tsx index 52a35cb85..b254b46d3 100644 --- a/frontend/src/hooks/api/auditLogs/queries.tsx +++ b/frontend/src/hooks/api/auditLogs/queries.tsx @@ -57,6 +57,7 @@ export const useGetAuditLogs = ( }, getNextPageParam: (lastPage, pages) => lastPage.length !== 0 ? pages.length * filters.limit : undefined, + placeholderData: (prev) => prev, ...options }); }; diff --git a/frontend/src/hooks/api/folderCommits/queries.tsx b/frontend/src/hooks/api/folderCommits/queries.tsx index 8d0883c5b..1bca7ce9a 100644 --- a/frontend/src/hooks/api/folderCommits/queries.tsx +++ b/frontend/src/hooks/api/folderCommits/queries.tsx @@ -1,8 +1,9 @@ -import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { useInfiniteQuery, useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { format } from "date-fns"; import { apiRequest } from "@app/config/request"; -import { CommitHistoryItem, CommitWithChanges, RollbackPreview } from "./types"; +import { Commit, CommitHistoryItem, CommitWithChanges, RollbackPreview } from "./types"; export const commitKeys = { count: ({ @@ -242,7 +243,6 @@ export const useGetFolderCommitHistory = ({ workspaceId, environment, directory, - offset = 0, limit = 20, search, sort = "desc" @@ -250,22 +250,33 @@ export const useGetFolderCommitHistory = ({ workspaceId: string; environment: string; directory: string; - offset?: number; limit?: number; search?: string; sort?: "asc" | "desc"; }) => { - return useQuery({ - queryKey: [ - commitKeys.history({ workspaceId, environment, directory }), - offset, - limit, - search, - sort - ], - queryFn: () => - fetchFolderCommitHistory(workspaceId, environment, directory, offset, limit, search, sort), - enabled: Boolean(workspaceId && environment) + return useInfiniteQuery({ + initialPageParam: 0, + queryKey: [commitKeys.history({ workspaceId, environment, directory }), limit, search, sort], + queryFn: ({ pageParam }) => + fetchFolderCommitHistory(workspaceId, environment, directory, pageParam, limit, search, sort), + enabled: Boolean(workspaceId && environment), + select: (data) => { + return (data?.pages ?? []) + ?.map((page) => page.commits) + .flat() + .reduce( + (acc, commit) => { + const date = format(new Date(commit.createdAt), "MMM d, yyyy"); + if (!acc[date]) { + acc[date] = []; + } + acc[date].push(commit); + return acc; + }, + {} as Record + ); + }, + getNextPageParam: (lastPage, pages) => (lastPage.hasMore ? pages.length * limit : undefined) }); }; diff --git a/frontend/src/hooks/api/folderCommits/types.ts b/frontend/src/hooks/api/folderCommits/types.ts index 878e3224d..a5f4e6df6 100644 --- a/frontend/src/hooks/api/folderCommits/types.ts +++ b/frontend/src/hooks/api/folderCommits/types.ts @@ -62,3 +62,16 @@ export type RollbackPreview = { folderPath: string; changes: RollbackChange[]; }; + +interface CommitActorMetadata { + email?: string; + name?: string; +} + +export interface Commit { + id: string; + message: string; + createdAt: string; + actorType: string; + actorMetadata?: CommitActorMetadata; +} diff --git a/frontend/src/hooks/api/identities/types.ts b/frontend/src/hooks/api/identities/types.ts index 69cb26e6c..1af1cc24c 100644 --- a/frontend/src/hooks/api/identities/types.ts +++ b/frontend/src/hooks/api/identities/types.ts @@ -51,7 +51,7 @@ export type IdentityMembershipOrg = { export type IdentityMembership = { id: string; identity: Identity; - project: Pick; + project: Pick; roles: Array< { id: string; diff --git a/frontend/src/hooks/api/projectTemplates/types.ts b/frontend/src/hooks/api/projectTemplates/types.ts index e9f76f149..f5ff22dff 100644 --- a/frontend/src/hooks/api/projectTemplates/types.ts +++ b/frontend/src/hooks/api/projectTemplates/types.ts @@ -1,9 +1,12 @@ import { TProjectRole } from "@app/hooks/api/roles/types"; +import { ProjectType } from "../workspace/types"; + export type TProjectTemplate = { id: string; name: string; description?: string; + type: ProjectType; roles: Pick[]; environments?: { name: string; slug: string; position: number }[] | null; createdAt: string; @@ -16,6 +19,7 @@ export type TProjectTemplateResponse = { projectTemplate: TProjectTemplate }; export type TCreateProjectTemplateDTO = { name: string; description?: string; + type?: ProjectType; }; export type TUpdateProjectTemplateDTO = Partial< diff --git a/frontend/src/hooks/api/secretFolders/types.ts b/frontend/src/hooks/api/secretFolders/types.ts index 33653ff72..dc9bce70f 100644 --- a/frontend/src/hooks/api/secretFolders/types.ts +++ b/frontend/src/hooks/api/secretFolders/types.ts @@ -4,11 +4,19 @@ export enum ReservedFolders { SecretReplication = "__reserve_replication_" } +export enum PendingAction { + Create = "create", + Update = "update", + Delete = "delete" +} + export type TSecretFolder = { id: string; name: string; description?: string; parentId?: string | null; + isPending?: boolean; + pendingAction?: PendingAction; }; export type TSecretFolderWithPath = TSecretFolder & { path: string }; diff --git a/frontend/src/hooks/api/secretRotationsV2/enums.ts b/frontend/src/hooks/api/secretRotationsV2/enums.ts index bb2765ffd..be692cee3 100644 --- a/frontend/src/hooks/api/secretRotationsV2/enums.ts +++ b/frontend/src/hooks/api/secretRotationsV2/enums.ts @@ -6,7 +6,8 @@ export enum SecretRotation { Auth0ClientSecret = "auth0-client-secret", AzureClientSecret = "azure-client-secret", LdapPassword = "ldap-password", - AwsIamUserSecret = "aws-iam-user-secret" + AwsIamUserSecret = "aws-iam-user-secret", + OktaClientSecret = "okta-client-secret" } export enum SecretRotationStatus { diff --git a/frontend/src/hooks/api/secretRotationsV2/types/index.ts b/frontend/src/hooks/api/secretRotationsV2/types/index.ts index e4b3b6ee1..06783944b 100644 --- a/frontend/src/hooks/api/secretRotationsV2/types/index.ts +++ b/frontend/src/hooks/api/secretRotationsV2/types/index.ts @@ -35,6 +35,11 @@ import { TMySqlCredentialsRotation, TMySqlCredentialsRotationGeneratedCredentialsResponse } from "./mysql-credentials-rotation"; +import { + TOktaClientSecretRotation, + TOktaClientSecretRotationGeneratedCredentialsResponse, + TOktaClientSecretRotationOption +} from "./okta-client-secret-rotation"; import { TOracleDBCredentialsRotation, TOracleDBCredentialsRotationGeneratedCredentialsResponse @@ -49,6 +54,7 @@ export type TSecretRotationV2 = ( | TAzureClientSecretRotation | TLdapPasswordRotation | TAwsIamUserSecretRotation + | TOktaClientSecretRotation ) & { secrets: (SecretV3RawSanitized | null)[]; }; @@ -58,7 +64,8 @@ export type TSecretRotationV2Option = | TAuth0ClientSecretRotationOption | TAzureClientSecretRotationOption | TLdapPasswordRotationOption - | TAwsIamUserSecretRotationOption; + | TAwsIamUserSecretRotationOption + | TOktaClientSecretRotationOption; export type TListSecretRotationV2Options = { secretRotationOptions: TSecretRotationV2Option[] }; @@ -72,7 +79,8 @@ export type TViewSecretRotationGeneratedCredentialsResponse = | TAuth0ClientSecretRotationGeneratedCredentialsResponse | TAzureClientSecretRotationGeneratedCredentialsResponse | TLdapPasswordRotationGeneratedCredentialsResponse - | TAwsIamUserSecretRotationGeneratedCredentialsResponse; + | TAwsIamUserSecretRotationGeneratedCredentialsResponse + | TOktaClientSecretRotationGeneratedCredentialsResponse; export type TCreateSecretRotationV2DTO = DiscriminativePick< TSecretRotationV2, @@ -124,6 +132,7 @@ export type TSecretRotationOptionMap = { [SecretRotation.AzureClientSecret]: TAzureClientSecretRotationOption; [SecretRotation.LdapPassword]: TLdapPasswordRotationOption; [SecretRotation.AwsIamUserSecret]: TAwsIamUserSecretRotationOption; + [SecretRotation.OktaClientSecret]: TOktaClientSecretRotationOption; }; export type TSecretRotationGeneratedCredentialsResponseMap = { @@ -135,4 +144,5 @@ export type TSecretRotationGeneratedCredentialsResponseMap = { [SecretRotation.AzureClientSecret]: TAzureClientSecretRotationGeneratedCredentialsResponse; [SecretRotation.LdapPassword]: TLdapPasswordRotationGeneratedCredentialsResponse; [SecretRotation.AwsIamUserSecret]: TAwsIamUserSecretRotationGeneratedCredentialsResponse; + [SecretRotation.OktaClientSecret]: TOktaClientSecretRotationGeneratedCredentialsResponse; }; diff --git a/frontend/src/hooks/api/secretRotationsV2/types/okta-client-secret-rotation.ts b/frontend/src/hooks/api/secretRotationsV2/types/okta-client-secret-rotation.ts new file mode 100644 index 000000000..2884f9b29 --- /dev/null +++ b/frontend/src/hooks/api/secretRotationsV2/types/okta-client-secret-rotation.ts @@ -0,0 +1,37 @@ +import { AppConnection } from "@app/hooks/api/appConnections/enums"; +import { SecretRotation } from "@app/hooks/api/secretRotationsV2"; +import { + TSecretRotationV2Base, + TSecretRotationV2GeneratedCredentialsResponseBase +} from "@app/hooks/api/secretRotationsV2/types/shared"; + +export type TOktaClientSecretRotation = TSecretRotationV2Base & { + type: SecretRotation.OktaClientSecret; + parameters: { + clientId: string; + }; + secretsMapping: { + clientId: string; + clientSecret: string; + }; +}; + +export type TOktaClientSecretRotationGeneratedCredentials = { + clientId: string; + clientSecret: string; +}; + +export type TOktaClientSecretRotationGeneratedCredentialsResponse = + TSecretRotationV2GeneratedCredentialsResponseBase< + SecretRotation.OktaClientSecret, + TOktaClientSecretRotationGeneratedCredentials + >; + +export type TOktaClientSecretRotationOption = { + name: string; + type: SecretRotation.OktaClientSecret; + connection: AppConnection.Okta; + template: { + secretsMapping: TOktaClientSecretRotation["secretsMapping"]; + }; +}; diff --git a/frontend/src/hooks/api/secretSyncs/enums.ts b/frontend/src/hooks/api/secretSyncs/enums.ts index dfba4bf4b..f29599a08 100644 --- a/frontend/src/hooks/api/secretSyncs/enums.ts +++ b/frontend/src/hooks/api/secretSyncs/enums.ts @@ -25,7 +25,8 @@ export enum SecretSync { Supabase = "supabase", Zabbix = "zabbix", Railway = "railway", - Checkly = "checkly" + Checkly = "checkly", + Bitbucket = "bitbucket" } export enum SecretSyncStatus { diff --git a/frontend/src/hooks/api/secretSyncs/types/bitbucket-sync.ts b/frontend/src/hooks/api/secretSyncs/types/bitbucket-sync.ts new file mode 100644 index 000000000..829b96da3 --- /dev/null +++ b/frontend/src/hooks/api/secretSyncs/types/bitbucket-sync.ts @@ -0,0 +1,17 @@ +import { AppConnection } from "@app/hooks/api/appConnections/enums"; +import { SecretSync } from "@app/hooks/api/secretSyncs"; +import { TRootSecretSync } from "@app/hooks/api/secretSyncs/types/root-sync"; + +export type TBitbucketSync = TRootSecretSync & { + destination: SecretSync.Bitbucket; + destinationConfig: { + workspaceSlug: string; + repositorySlug: string; + environmentId?: string; + }; + connection: { + app: AppConnection.Bitbucket; + name: string; + id: string; + }; +}; diff --git a/frontend/src/hooks/api/secretSyncs/types/index.ts b/frontend/src/hooks/api/secretSyncs/types/index.ts index df02872ad..daffac56a 100644 --- a/frontend/src/hooks/api/secretSyncs/types/index.ts +++ b/frontend/src/hooks/api/secretSyncs/types/index.ts @@ -8,6 +8,7 @@ import { TAwsSecretsManagerSync } from "./aws-secrets-manager-sync"; import { TAzureAppConfigurationSync } from "./azure-app-configuration-sync"; import { TAzureDevOpsSync } from "./azure-devops-sync"; import { TAzureKeyVaultSync } from "./azure-key-vault-sync"; +import { TBitbucketSync } from "./bitbucket-sync"; import { TCamundaSync } from "./camunda-sync"; import { TChecklySync } from "./checkly-sync"; import { TCloudflarePagesSync } from "./cloudflare-pages-sync"; @@ -63,7 +64,8 @@ export type TSecretSync = | TZabbixSync | TRailwaySync | TChecklySync - | TSupabaseSync; + | TSupabaseSync + | TBitbucketSync; export type TListSecretSyncs = { secretSyncs: TSecretSync[] }; diff --git a/frontend/src/hooks/api/secrets/mutations.tsx b/frontend/src/hooks/api/secrets/mutations.tsx index 82bf623e6..11ebad4b1 100644 --- a/frontend/src/hooks/api/secrets/mutations.tsx +++ b/frontend/src/hooks/api/secrets/mutations.tsx @@ -2,9 +2,14 @@ import { MutationOptions, useMutation, useQueryClient } from "@tanstack/react-qu import { apiRequest } from "@app/config/request"; import { dashboardKeys } from "@app/hooks/api/dashboard/queries"; +import { + PendingChanges, + PendingSecretUpdate +} from "@app/pages/secret-manager/SecretDashboardPage/SecretMainPage.store"; import { commitKeys } from "../folderCommits/queries"; import { secretApprovalRequestKeys } from "../secretApprovalRequest/queries"; +import { PendingAction } from "../secretFolders/types"; import { secretSnapshotKeys } from "../secretSnapshots/queries"; import { secretKeys } from "./queries"; import { @@ -420,3 +425,102 @@ export const useBackfillSecretReference = () => return data.message; } }); + +export const useCreateCommit = () => { + const queryClient = useQueryClient(); + return useMutation< + object, + object, + { + workspaceId: string; + environment: string; + secretPath: string; + pendingChanges: PendingChanges; + message: string; + } + >({ + mutationFn: async ({ workspaceId, environment, secretPath, pendingChanges, message }) => { + const { data } = await apiRequest.post("/api/v1/pit/batch/commit", { + projectId: workspaceId, + environment, + secretPath, + changes: { + secrets: { + create: + pendingChanges.secrets + .filter((change) => change.type === PendingAction.Create) + .map((change) => ({ + secretKey: change.secretKey, + secretValue: change.secretValue, + secretComment: change.secretComment, + skipMultilineEncoding: change.skipMultilineEncoding, + tagIds: change.tags?.map((tag) => tag.id), + secretMetadata: change.secretMetadata + })) || [], + update: + pendingChanges.secrets + .filter((change) => change.type === PendingAction.Update) + .map((change: PendingSecretUpdate) => ({ + secretKey: change.secretKey, + newSecretName: change.newSecretName, + secretValue: + change.secretValue === "" + ? "" + : change.secretValue || change.existingSecret.value, + secretComment: + change.secretComment === "" + ? "" + : change.secretComment || change.existingSecret.comment, + skipMultilineEncoding: + change.skipMultilineEncoding !== undefined + ? change.skipMultilineEncoding + : change.existingSecret.skipMultilineEncoding, + tagIds: + change.tags?.map((tag) => tag.id) || + change.existingSecret.tags?.map((tag) => tag.id), + secretMetadata: change.secretMetadata || change.existingSecret.secretMetadata + })) || [], + delete: + pendingChanges.secrets.filter((change) => change.type === PendingAction.Delete) || [] + }, + folders: { + create: + pendingChanges.folders.filter((change) => change.type === PendingAction.Create) || [], + update: + pendingChanges.folders + .filter((change) => change.type === PendingAction.Update) + .map((change) => ({ + ...change, + description: change.description || null + })) || [], + delete: + pendingChanges.folders.filter((change) => change.type === PendingAction.Delete) || [] + } + }, + message + }); + return data; + }, + onSuccess: (_, { workspaceId, environment, secretPath }) => { + queryClient.invalidateQueries({ + queryKey: dashboardKeys.getDashboardSecrets({ projectId: workspaceId, secretPath }) + }); + queryClient.invalidateQueries({ + queryKey: secretKeys.getProjectSecret({ workspaceId, environment, secretPath }) + }); + queryClient.invalidateQueries({ + queryKey: secretSnapshotKeys.list({ environment, workspaceId, directory: secretPath }) + }); + queryClient.invalidateQueries({ + queryKey: secretSnapshotKeys.count({ environment, workspaceId, directory: secretPath }) + }); + queryClient.invalidateQueries({ + queryKey: commitKeys.count({ workspaceId, environment, directory: secretPath }) + }); + queryClient.invalidateQueries({ + queryKey: commitKeys.history({ workspaceId, environment, directory: secretPath }) + }); + queryClient.invalidateQueries({ queryKey: secretApprovalRequestKeys.count({ workspaceId }) }); + } + }); +}; diff --git a/frontend/src/hooks/api/secrets/types.ts b/frontend/src/hooks/api/secrets/types.ts index fa597169f..29da8e578 100644 --- a/frontend/src/hooks/api/secrets/types.ts +++ b/frontend/src/hooks/api/secrets/types.ts @@ -1,5 +1,6 @@ import { ProjectPermissionActions } from "@app/context"; +import { PendingAction } from "../secretFolders/types"; import type { WsTag } from "../tags/types"; export enum SecretType { @@ -66,6 +67,8 @@ export type SecretV3RawSanitized = { isRotatedSecret?: boolean; secretReminderRecipients?: SecretReminderRecipient[]; rotationId?: string; + isPending?: boolean; + pendingAction?: PendingAction; }; export type SecretV3Raw = { diff --git a/frontend/src/hooks/api/workspace/queries.tsx b/frontend/src/hooks/api/workspace/queries.tsx index 260b02145..6408d0e22 100644 --- a/frontend/src/hooks/api/workspace/queries.tsx +++ b/frontend/src/hooks/api/workspace/queries.tsx @@ -255,12 +255,13 @@ export const useCreateWorkspace = () => { const queryClient = useQueryClient(); return useMutation<{ data: { project: Workspace } }, object, CreateWorkspaceDTO>({ - mutationFn: async ({ projectName, projectDescription, kmsKeyId, template }) => + mutationFn: async ({ projectName, projectDescription, kmsKeyId, template, type }) => createWorkspace({ projectName, projectDescription, kmsKeyId, - template + template, + type }), onSuccess: () => { queryClient.invalidateQueries({ @@ -280,8 +281,7 @@ export const useUpdateProject = () => { newProjectDescription, newSlug, secretSharing, - showSnapshotsLegacy, - defaultProduct + showSnapshotsLegacy }) => { const { data } = await apiRequest.patch<{ workspace: Workspace }>( `/api/v1/workspace/${projectID}`, @@ -289,7 +289,6 @@ export const useUpdateProject = () => { name: newProjectName, description: newProjectDescription, slug: newSlug, - defaultProduct, secretSharing, showSnapshotsLegacy } diff --git a/frontend/src/hooks/api/workspace/types.ts b/frontend/src/hooks/api/workspace/types.ts index 5249f39ec..7d6f68821 100644 --- a/frontend/src/hooks/api/workspace/types.ts +++ b/frontend/src/hooks/api/workspace/types.ts @@ -24,7 +24,7 @@ export type Workspace = { __v: number; id: string; name: string; - defaultProduct: ProjectType; + type: ProjectType; description?: string; orgId: string; version: ProjectVersion; @@ -68,6 +68,7 @@ export type TGetUpgradeProjectStatusDTO = { // mutation dto export type CreateWorkspaceDTO = { projectName: string; + type: ProjectType; projectDescription?: string; kmsKeyId?: string; template?: string; @@ -80,7 +81,6 @@ export type UpdateProjectDTO = { newSlug?: string; secretSharing?: boolean; showSnapshotsLegacy?: boolean; - defaultProduct?: ProjectType; }; export type UpdatePitVersionLimitDTO = { projectSlug: string; pitVersionLimit: number }; @@ -184,6 +184,7 @@ export type TSearchProjectsDTO = { name?: string; limit?: number; offset?: number; + type?: ProjectType; options?: { enabled?: boolean }; orderBy?: ProjectIdentityOrderBy; orderDirection?: OrderByDirection; diff --git a/frontend/src/hooks/useNavigationBlocker.tsx b/frontend/src/hooks/useNavigationBlocker.tsx new file mode 100644 index 000000000..e427d6a7d --- /dev/null +++ b/frontend/src/hooks/useNavigationBlocker.tsx @@ -0,0 +1,40 @@ +import { useCallback } from "react"; +import { useBlocker } from "@tanstack/react-router"; + +import { + BatchContext, + useBatchModeActions +} from "@app/pages/secret-manager/SecretDashboardPage/SecretMainPage.store"; + +type TNavigationBlockerReturn = { + isBlocked: boolean; +}; + +export const useNavigationBlocker = ({ + shouldBlock = false, + message = "Are you sure you want to leave? You may have unsaved changes.", + context +}: { + shouldBlock: boolean; + message: string; + context: BatchContext; +}): TNavigationBlockerReturn => { + const { clearAllPendingChanges } = useBatchModeActions(); + const blockerFn = useCallback(() => { + if (!shouldBlock) return false; + + // eslint-disable-next-line no-alert + const confirmed = window.confirm(message); + if (confirmed) { + clearAllPendingChanges(context); + } + + return !confirmed; + }, [shouldBlock, message, context]); + + useBlocker(blockerFn, shouldBlock); + + return { + isBlocked: shouldBlock + }; +}; diff --git a/frontend/src/layouts/KmsLayout/KmsLayout.tsx b/frontend/src/layouts/KmsLayout/KmsLayout.tsx index 3e671a0e2..dbe1192f7 100644 --- a/frontend/src/layouts/KmsLayout/KmsLayout.tsx +++ b/frontend/src/layouts/KmsLayout/KmsLayout.tsx @@ -1,11 +1,16 @@ +import { faCog, faCube, faHome, faLock, faUsers } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Link, Outlet } from "@tanstack/react-router"; import { motion } from "framer-motion"; -import { Menu, MenuItem } from "@app/components/v2"; -import { useWorkspace } from "@app/context"; +import { Lottie, Menu, MenuGroup, MenuItem } from "@app/components/v2"; +import { useProjectPermission, useWorkspace } from "@app/context"; + +import { AssumePrivilegeModeBanner } from "../ProjectLayout/components/AssumePrivilegeModeBanner"; export const KmsLayout = () => { const { currentWorkspace } = useWorkspace(); + const { assumedPrivilegeDetails } = useProjectPermission(); return ( @@ -19,40 +24,106 @@ export const KmsLayout = () => { className="dark w-full border-r border-mineshaft-600 bg-gradient-to-tr from-mineshaft-700 via-mineshaft-800 to-mineshaft-900 md:w-60" > - KMS + + + KMS + - - {({ isActive }) => Overview} + + + {({ isActive }) => ( + + + + + + Overview + + + )} + + + {({ isActive }) => ( + + + + + + KMIP + + + )} + + + + + {({ isActive }) => ( + + + + + + Access Management + + + )} + + + {({ isActive }) => ( + + + + + + Settings + + + )} + + + + + + + + + + + } + > + Organization Home + - - {({ isActive }) => KMIP} - - { - // - // {({ isActive }) => Settings} - // - } + {assumedPrivilegeDetails && } diff --git a/frontend/src/layouts/OrganizationLayout/components/OrgSidebar/OrgSidebar.tsx b/frontend/src/layouts/OrganizationLayout/components/OrgSidebar/OrgSidebar.tsx index 0bab1fcb5..7b2e5f154 100644 --- a/frontend/src/layouts/OrganizationLayout/components/OrgSidebar/OrgSidebar.tsx +++ b/frontend/src/layouts/OrganizationLayout/components/OrgSidebar/OrgSidebar.tsx @@ -1,12 +1,12 @@ import { faBook, faCog, - faCubes, faDoorClosed, faInfinity, faMoneyBill, faPlug, faShare, + faTable, faUserCog, faUsers, faUserTie @@ -56,7 +56,7 @@ export const OrgSidebar = ({ isHidden }: Props) => { - + Projects diff --git a/frontend/src/layouts/PkiManagerLayout/PkiManagerLayout.tsx b/frontend/src/layouts/PkiManagerLayout/PkiManagerLayout.tsx index 00b9f4538..cf9f22580 100644 --- a/frontend/src/layouts/PkiManagerLayout/PkiManagerLayout.tsx +++ b/frontend/src/layouts/PkiManagerLayout/PkiManagerLayout.tsx @@ -1,14 +1,27 @@ import { useTranslation } from "react-i18next"; -import { faMobile } from "@fortawesome/free-solid-svg-icons"; +import { + faBell, + faCertificate, + faCog, + faFileLines, + faHome, + faMobile, + faSitemap, + faStamp, + faUsers +} from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Link, Outlet } from "@tanstack/react-router"; import { motion } from "framer-motion"; -import { Menu, MenuItem } from "@app/components/v2"; -import { useWorkspace } from "@app/context"; +import { Lottie, Menu, MenuGroup, MenuItem } from "@app/components/v2"; +import { useProjectPermission, useWorkspace } from "@app/context"; + +import { AssumePrivilegeModeBanner } from "../ProjectLayout/components/AssumePrivilegeModeBanner"; export const PkiManagerLayout = () => { const { currentWorkspace } = useWorkspace(); + const { assumedPrivilegeDetails } = useProjectPermission(); const { t } = useTranslation(); return ( @@ -24,70 +37,157 @@ export const PkiManagerLayout = () => { className="dark w-full border-r border-mineshaft-600 bg-gradient-to-tr from-mineshaft-700 via-mineshaft-800 to-mineshaft-900 md:w-60" > - + + PKI Manager - - {({ isActive }) => Subscribers} + + + {({ isActive }) => ( + + + + + + Subscribers + + + )} + + + {({ isActive }) => ( + + + + + + Certificate Templates + + + )} + + + {({ isActive }) => ( + + + + + + Certificates + + + )} + + + {({ isActive }) => ( + + + + + + Certificates Authority + + + )} + + + {({ isActive }) => ( + + + + + + Alerting + + + )} + + + + + {({ isActive }) => ( + + + + + + Access Management + + + )} + + + {({ isActive }) => ( + + + + + + Settings + + + )} + + + + + + + + + + + } + > + Organization Home + - - {({ isActive }) => ( - Certificate Templates - )} - - - {({ isActive }) => Certificates} - - - {({ isActive }) => ( - Certificates Authorities - )} - - - {({ isActive }) => Alerting} - - { - // - // {({ isActive }) => Settings} - // - } + {assumedPrivilegeDetails && } diff --git a/frontend/src/layouts/ProjectGeneralLayout/ProjectGeneralLayout.tsx b/frontend/src/layouts/ProjectGeneralLayout/ProjectGeneralLayout.tsx deleted file mode 100644 index f2343eb66..000000000 --- a/frontend/src/layouts/ProjectGeneralLayout/ProjectGeneralLayout.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { Link, Outlet } from "@tanstack/react-router"; -import { motion } from "framer-motion"; - -import { Menu, MenuItem } from "@app/components/v2"; -import { useWorkspace } from "@app/context"; - -export const ProjectGeneralLayout = () => { - const { currentWorkspace } = useWorkspace(); - - return ( - - - - - - Project Overview - - - - - {({ isActive }) => Access Control} - - - {({ isActive }) => Project Settings} - - - - - - - - - - - ); -}; diff --git a/frontend/src/layouts/ProjectGeneralLayout/index.tsx b/frontend/src/layouts/ProjectGeneralLayout/index.tsx deleted file mode 100644 index d048fbebc..000000000 --- a/frontend/src/layouts/ProjectGeneralLayout/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { ProjectGeneralLayout } from "./ProjectGeneralLayout"; diff --git a/frontend/src/layouts/ProjectLayout/ProjectLayout.tsx b/frontend/src/layouts/ProjectLayout/ProjectLayout.tsx deleted file mode 100644 index b239dc17c..000000000 --- a/frontend/src/layouts/ProjectLayout/ProjectLayout.tsx +++ /dev/null @@ -1,327 +0,0 @@ -import { useTranslation } from "react-i18next"; -import { faDotCircle, faMobile, faWindowMaximize } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { Link, Outlet, useLocation } from "@tanstack/react-router"; -import { motion } from "framer-motion"; -import { twMerge } from "tailwind-merge"; - -import { ShouldWrap } from "@app/components/utilities/ShouldWrapComponent"; -import { - Divider, - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuTrigger, - Lottie, - Menu, - MenuItem, - Tooltip -} from "@app/components/v2"; -import { useProjectPermission, useWorkspace } from "@app/context"; -import { getCurrentProductFromUrl } from "@app/helpers/project"; -import { useLocalStorageState } from "@app/hooks"; -import { ProjectType } from "@app/hooks/api/workspace/types"; - -import { AssumePrivilegeModeBanner } from "./components/AssumePrivilegeModeBanner"; - -enum SidebarStyle { - Expanded = "expanded", - Collapsed = "collapsed", - ExpandOnHover = "expand-on-hover" -} -const MIN_SIDEBAR_SIZE = "55px"; -const MAX_SIDEBAR_SIZE = "220px"; -// This is a generic layout shared by all types of projects. -// If the product layout differs significantly, create a new layout as needed. -export const ProjectLayout = () => { - const location = useLocation(); - const { currentWorkspace } = useWorkspace(); - const [sidebarStyle, setSidebarStyle] = useLocalStorageState( - "project-sidebar-style", - SidebarStyle.ExpandOnHover - ); - - const { t } = useTranslation(); - const { assumedPrivilegeDetails } = useProjectPermission(); - - const minSidebarWidth = - sidebarStyle === SidebarStyle.Expanded ? MAX_SIDEBAR_SIZE : MIN_SIDEBAR_SIZE; - const maxSidebarWidth = - sidebarStyle === SidebarStyle.Collapsed ? MIN_SIDEBAR_SIZE : MAX_SIDEBAR_SIZE; - - const currentProductType = getCurrentProductFromUrl(location.pathname); - const isSecretManager = currentProductType === ProjectType.SecretManager; - const isPki = currentProductType === ProjectType.CertificateManager; - const isKms = currentProductType === ProjectType.KMS; - const isSsh = currentProductType === ProjectType.SSH; - const isSecretScanning = currentProductType === ProjectType.SecretScanning; - - return ( - <> - - - - - - - - } - > - {isSecretManager && ( - - )} - Secret Manager - - - - - - } - > - {isPki && } - PKI Manager - - - - - - } - > - {isKms && } - KMS - - - - - - - } - > - {isSsh && } - SSH - - - - - - - } - > - {isSecretScanning && ( - - )} - Secret Scanning - - - - - - - - - {({ isActive }) => ( - - } - > - {isActive && ( - - )} - Access Control - - )} - - - - - {({ isActive }) => ( - - } - > - {isActive && ( - - )} - Project Settings - - )} - - - - - - - - - - } - > - Sidebar Control - - - - - - ) - } - onClick={() => setSidebarStyle(SidebarStyle.Expanded)} - > - Expanded - - - ) - } - onClick={() => setSidebarStyle(SidebarStyle.Collapsed)} - > - Collapsed - - - ) - } - onClick={() => setSidebarStyle(SidebarStyle.ExpandOnHover)} - > - Expand on hover - - - - - - - - {assumedPrivilegeDetails && } - - - - - - - - {` ${t("common.no-mobile")} `} - - - > - ); -}; diff --git a/frontend/src/layouts/ProjectLayout/components/AssumePrivilegeModeBanner/AssumePrivilegeModeBanner.tsx b/frontend/src/layouts/ProjectLayout/components/AssumePrivilegeModeBanner/AssumePrivilegeModeBanner.tsx index 52882ba6d..2b4fcff80 100644 --- a/frontend/src/layouts/ProjectLayout/components/AssumePrivilegeModeBanner/AssumePrivilegeModeBanner.tsx +++ b/frontend/src/layouts/ProjectLayout/components/AssumePrivilegeModeBanner/AssumePrivilegeModeBanner.tsx @@ -3,10 +3,9 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Button } from "@app/components/v2"; import { useProjectPermission, useWorkspace } from "@app/context"; -import { getCurrentProductFromUrl, getProjectHomePage } from "@app/helpers/project"; +import { getProjectHomePage } from "@app/helpers/project"; import { useRemoveAssumeProjectPrivilege } from "@app/hooks/api"; import { ActorType } from "@app/hooks/api/auditLogs/enums"; -import { ProjectType } from "@app/hooks/api/workspace/types"; export const AssumePrivilegeModeBanner = () => { const { currentWorkspace } = useWorkspace(); @@ -37,10 +36,7 @@ export const AssumePrivilegeModeBanner = () => { }, { onSuccess: () => { - const url = getProjectHomePage( - getCurrentProductFromUrl(window.location.href) || ProjectType.SecretManager - ); - + const url = getProjectHomePage(currentWorkspace.type); window.location.href = url.replace("$projectId", currentWorkspace.id); } } diff --git a/frontend/src/layouts/ProjectLayout/components/MenuIconButton/Copy.tsx b/frontend/src/layouts/ProjectLayout/components/MenuIconButton/Copy.tsx deleted file mode 100644 index f7c30c883..000000000 --- a/frontend/src/layouts/ProjectLayout/components/MenuIconButton/Copy.tsx +++ /dev/null @@ -1,121 +0,0 @@ -import { ComponentPropsWithRef, ElementType, useRef } from "react"; -import { DotLottie, DotLottieReact } from "@lottiefiles/dotlottie-react"; -import { twMerge } from "tailwind-merge"; - -import { MenuItemProps } from "@app/components/v2"; - -export const MenuIconButton = ({ - children, - icon, - className, - isDisabled, - isSelected, - as: Item = "div", - description, - // wrapping in forward ref with generic component causes the loss of ts definitions on props - inputRef, - lottieIconMode = "forward", - ...props -}: MenuItemProps & - ComponentPropsWithRef & { lottieIconMode?: "reverse" | "forward" }): JSX.Element => { - const iconRef = useRef(null); - return ( - - iconRef.current?.play()} - onMouseLeave={() => iconRef.current?.stop()} - ref={inputRef} - {...props} - > - - {icon && ( - - { - iconRef.current = el; - }} - src={`/lotties/${icon}.json`} - loop - className="h-full w-full" - mode={lottieIconMode} - /> - - )} - - {children} - - - - ); -}; - -// export const MenuIconButton = ({ -// children, -// icon, -// className, -// isDisabled, -// isSelected, -// as: Item = "div", -// description, -// // wrapping in forward ref with generic component causes the loss of ts definitions on props -// inputRef, -// lottieIconMode = "forward", -// ...props -// }: MenuItemProps & -// ComponentPropsWithRef & { lottieIconMode?: "reverse" | "forward" }): JSX.Element => { -// const iconRef = useRef(null); -// return ( -// -// iconRef.current?.play()} -// onMouseLeave={() => iconRef.current?.stop()} -// ref={inputRef} -// {...props} -// > -// -// {icon && ( -// -// { -// iconRef.current = el; -// }} -// src={`/lotties/${icon}.json`} -// loop -// className="h-full w-full" -// mode={lottieIconMode} -// /> -// -// )} -// -// {children} -// -// -// -// ); -// }; diff --git a/frontend/src/layouts/ProjectLayout/components/MenuIconButton/MenuIconButton.tsx b/frontend/src/layouts/ProjectLayout/components/MenuIconButton/MenuIconButton.tsx deleted file mode 100644 index bff09423c..000000000 --- a/frontend/src/layouts/ProjectLayout/components/MenuIconButton/MenuIconButton.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import { ComponentPropsWithRef, ElementType, useRef } from "react"; -import { DotLottie, DotLottieReact } from "@lottiefiles/dotlottie-react"; -import { twMerge } from "tailwind-merge"; - -import { MenuItemProps } from "@app/components/v2"; - -export const MenuIconButton = ({ - children, - icon, - className, - isDisabled, - isSelected, - as: Item = "div", - description, - // wrapping in forward ref with generic component causes the loss of ts definitions on props - inputRef, - lottieIconMode = "forward", - ...props -}: MenuItemProps & - ComponentPropsWithRef & { lottieIconMode?: "reverse" | "forward" }): JSX.Element => { - const iconRef = useRef(null); - return ( - - iconRef.current?.play()} - onMouseLeave={() => iconRef.current?.stop()} - ref={inputRef} - {...props} - > - - {icon && ( - - { - iconRef.current = el; - }} - src={`/lotties/${icon}.json`} - loop - className="h-full w-full" - mode={lottieIconMode} - /> - - )} - - {children} - - - - ); -}; diff --git a/frontend/src/layouts/ProjectLayout/components/MenuIconButton/index.tsx b/frontend/src/layouts/ProjectLayout/components/MenuIconButton/index.tsx deleted file mode 100644 index 6655c7091..000000000 --- a/frontend/src/layouts/ProjectLayout/components/MenuIconButton/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { MenuIconButton } from "./MenuIconButton"; diff --git a/frontend/src/layouts/ProjectLayout/components/ProjectSelect/ProjectSelect.tsx b/frontend/src/layouts/ProjectLayout/components/ProjectSelect/ProjectSelect.tsx index 80fcee1dc..b66717a5c 100644 --- a/frontend/src/layouts/ProjectLayout/components/ProjectSelect/ProjectSelect.tsx +++ b/frontend/src/layouts/ProjectLayout/components/ProjectSelect/ProjectSelect.tsx @@ -31,14 +31,13 @@ import { useSubscription, useWorkspace } from "@app/context"; -import { getCurrentProductFromUrl, getProjectHomePage } from "@app/helpers/project"; +import { getProjectHomePage } from "@app/helpers/project"; import { usePopUp } from "@app/hooks"; import { useGetUserWorkspaces } from "@app/hooks/api"; import { useUpdateUserProjectFavorites } from "@app/hooks/api/users/mutation"; import { useGetUserProjectFavorites } from "@app/hooks/api/users/queries"; import { Workspace } from "@app/hooks/api/workspace/types"; -// TODO(pta): add search to project select export const ProjectSelect = () => { const [searchProject, setSearchProject] = useState(""); const { currentWorkspace } = useWorkspace(); @@ -102,9 +101,7 @@ export const ProjectSelect = () => { { - + {currentWorkspace?.name} @@ -161,7 +158,7 @@ export const ProjectSelect = () => { // to reproduce change this back to router.push and switch between two projects with different env count // look into this on dashboard revamp const url = linkOptions({ - to: getProjectHomePage(workspace.defaultProduct), + to: getProjectHomePage(workspace.type), params: { projectId: workspace.id } diff --git a/frontend/src/layouts/ProjectLayout/components/SidebarHeader/SidebarHeader.tsx b/frontend/src/layouts/ProjectLayout/components/SidebarHeader/SidebarHeader.tsx deleted file mode 100644 index dc74fdad5..000000000 --- a/frontend/src/layouts/ProjectLayout/components/SidebarHeader/SidebarHeader.tsx +++ /dev/null @@ -1,179 +0,0 @@ -import { - faAngleDown, - faArrowLeft, - faArrowUpRightFromSquare, - faCheck -} from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { Link, useNavigate } from "@tanstack/react-router"; - -import { - Button, - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuTrigger -} from "@app/components/v2"; -import { useOrganization, useUser } from "@app/context"; -import { useGetOrganizations, useLogoutUser } from "@app/hooks/api"; -import { AuthMethod } from "@app/hooks/api/users/types"; - -type Prop = { - onChangeOrg: (orgId: string) => void; -}; - -export const SidebarHeader = ({ onChangeOrg }: Prop) => { - const { currentOrg } = useOrganization(); - const { user } = useUser(); - const navigate = useNavigate(); - const { data: orgs } = useGetOrganizations(); - - const logout = useLogoutUser(); - const logOutUser = async () => { - try { - console.log("Logging out..."); - await logout.mutateAsync(); - navigate({ to: "/login" }); - } catch (error) { - console.error(error); - } - }; - - return ( - - - - - - - - - - - {currentOrg?.name.charAt(0)} - - - {currentOrg?.name} - - - - - - {user?.username} - {orgs?.map((org) => { - return ( - - { - if (currentOrg?.id === org.id) return; - - if (org.authEnforced) { - // org has an org-level auth method enabled (e.g. SAML) - // -> logout + redirect to SAML SSO - - await logout.mutateAsync(); - if (org.orgAuthMethod === AuthMethod.OIDC) { - window.open(`/api/v1/sso/oidc/login?orgSlug=${org.slug}`); - } else { - window.open(`/api/v1/sso/redirect/saml2/organizations/${org.slug}`); - } - window.close(); - return; - } - - onChangeOrg(org?.id); - }} - variant="plain" - colorSchema="secondary" - size="xs" - className="flex w-full items-center justify-start p-0 font-normal" - leftIcon={ - currentOrg?.id === org.id && ( - - ) - } - > - - {org.name} - - - - ); - })} - - - - Log Out - - - - - - - {user?.firstName?.charAt(0)} - {user?.lastName && user?.lastName?.charAt(0)} - - - - {user?.username} - - Personal Settings - - - - Documentation - - - - - - Join Slack Community - - - - {user?.superAdmin && ( - - - Server Admin Console - - - )} - - - Organization Admin Console - - - - - Log Out - - - - - ); -}; diff --git a/frontend/src/layouts/ProjectLayout/components/SidebarHeader/index.tsx b/frontend/src/layouts/ProjectLayout/components/SidebarHeader/index.tsx deleted file mode 100644 index bdc4db6ef..000000000 --- a/frontend/src/layouts/ProjectLayout/components/SidebarHeader/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { SidebarHeader } from "./SidebarHeader"; diff --git a/frontend/src/layouts/ProjectLayout/index.tsx b/frontend/src/layouts/ProjectLayout/index.tsx deleted file mode 100644 index ab759db95..000000000 --- a/frontend/src/layouts/ProjectLayout/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { ProjectLayout } from "./ProjectLayout"; diff --git a/frontend/src/layouts/SecretManagerLayout/SecretManagerLayout.tsx b/frontend/src/layouts/SecretManagerLayout/SecretManagerLayout.tsx index ed1857334..7a1eb932a 100644 --- a/frontend/src/layouts/SecretManagerLayout/SecretManagerLayout.tsx +++ b/frontend/src/layouts/SecretManagerLayout/SecretManagerLayout.tsx @@ -1,19 +1,31 @@ import { useTranslation } from "react-i18next"; -import { faMobile } from "@fortawesome/free-solid-svg-icons"; +import { + faArrowsSpin, + faCheckToSlot, + faCog, + faHome, + faMobile, + faPuzzlePiece, + faUsers, + faVault +} from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Link, Outlet } from "@tanstack/react-router"; import { motion } from "framer-motion"; -import { Badge, Menu, MenuItem } from "@app/components/v2"; -import { useWorkspace } from "@app/context"; +import { Badge, Lottie, Menu, MenuGroup, MenuItem } from "@app/components/v2"; +import { useProjectPermission, useWorkspace } from "@app/context"; import { useGetAccessRequestsCount, useGetSecretApprovalRequestCount, useGetSecretRotations } from "@app/hooks/api"; +import { AssumePrivilegeModeBanner } from "../ProjectLayout/components/AssumePrivilegeModeBanner"; + export const SecretManagerLayout = () => { const { currentWorkspace } = useWorkspace(); + const { assumedPrivilegeDetails } = useProjectPermission(); const { t } = useTranslation(); const workspaceId = currentWorkspace?.id || ""; @@ -50,73 +62,150 @@ export const SecretManagerLayout = () => { className="dark w-full border-r border-mineshaft-600 bg-gradient-to-tr from-mineshaft-700 via-mineshaft-800 to-mineshaft-900 md:w-60" > - + + Secrets Manager - - {({ isActive }) => ( - {t("nav.menu.secrets")} - )} - - - {({ isActive }) => ( - {t("nav.menu.integrations")} - )} - - {Boolean(secretRotations?.length) && ( + - {({ isActive }) => Secret Rotation} + {({ isActive }) => ( + + + + + + Secrets + + + )} - )} - - {({ isActive }) => ( - - Approvals - {Boolean( - secretApprovalReqCount?.open || accessApprovalRequestCount?.pendingCount - ) && ( - - {pendingRequestsCount} - + + {({ isActive }) => ( + + + + + + Integrations + + + )} + + {Boolean(secretRotations?.length) && ( + + {({ isActive }) => ( + + + + + + Secret Rotations + + )} - + )} - - - {({ isActive }) => Settings} + + {({ isActive }) => ( + + + + + + Approvals + {Boolean( + secretApprovalReqCount?.open || + accessApprovalRequestCount?.pendingCount + ) && ( + + {pendingRequestsCount} + + )} + + + )} + + + + + {({ isActive }) => ( + + + + + + Access Management + + + )} + + + {({ isActive }) => ( + + + + + + Settings + + + )} + + + + + + + + + + + } + > + Organization Home + + {assumedPrivilegeDetails && } diff --git a/frontend/src/layouts/SecretScanningLayout/SecretScanningLayout.tsx b/frontend/src/layouts/SecretScanningLayout/SecretScanningLayout.tsx index 113d793e5..8c54b6a1e 100644 --- a/frontend/src/layouts/SecretScanningLayout/SecretScanningLayout.tsx +++ b/frontend/src/layouts/SecretScanningLayout/SecretScanningLayout.tsx @@ -1,11 +1,22 @@ +import { + faCog, + faDatabase, + faHome, + faMagnifyingGlass, + faUsers +} from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Link, Outlet } from "@tanstack/react-router"; import { motion } from "framer-motion"; -import { Menu, MenuItem } from "@app/components/v2"; -import { useWorkspace } from "@app/context"; +import { Lottie, Menu, MenuGroup, MenuItem } from "@app/components/v2"; +import { useProjectPermission, useWorkspace } from "@app/context"; + +import { AssumePrivilegeModeBanner } from "../ProjectLayout/components/AssumePrivilegeModeBanner"; export const SecretScanningLayout = () => { const { currentWorkspace } = useWorkspace(); + const { assumedPrivilegeDetails } = useProjectPermission(); return ( @@ -19,40 +30,106 @@ export const SecretScanningLayout = () => { className="dark w-full border-r border-mineshaft-600 bg-gradient-to-tr from-mineshaft-700 via-mineshaft-800 to-mineshaft-900 md:w-60" > - + + Secret Scanning - - {({ isActive }) => Data Sources} - - - {({ isActive }) => Findings} - - - {({ isActive }) => Settings} + + + {({ isActive }) => ( + + + + + + Data Sources + + + )} + + + {({ isActive }) => ( + + + + + + Findings + + + )} + + + + + {({ isActive }) => ( + + + + + + Access Management + + + )} + + + {({ isActive }) => ( + + + + + + Settings + + + )} + + + + + + + + + + + } + > + Organization Home + + {assumedPrivilegeDetails && } diff --git a/frontend/src/layouts/SshLayout/SshLayout.tsx b/frontend/src/layouts/SshLayout/SshLayout.tsx index c62f91ab1..50ce87af9 100644 --- a/frontend/src/layouts/SshLayout/SshLayout.tsx +++ b/frontend/src/layouts/SshLayout/SshLayout.tsx @@ -1,12 +1,22 @@ +import { faCog, faHome, faServer, faStamp, faUsers } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Link, Outlet } from "@tanstack/react-router"; import { motion } from "framer-motion"; import { ProjectPermissionCan } from "@app/components/permissions"; -import { Menu, MenuItem } from "@app/components/v2"; -import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context"; +import { Lottie, Menu, MenuGroup, MenuItem } from "@app/components/v2"; +import { + ProjectPermissionActions, + ProjectPermissionSub, + useProjectPermission, + useWorkspace +} from "@app/context"; + +import { AssumePrivilegeModeBanner } from "../ProjectLayout/components/AssumePrivilegeModeBanner"; export const SshLayout = () => { const { currentWorkspace } = useWorkspace(); + const { assumedPrivilegeDetails } = useProjectPermission(); return ( @@ -20,49 +30,116 @@ export const SshLayout = () => { className="dark w-full border-r border-mineshaft-600 bg-gradient-to-tr from-mineshaft-700 via-mineshaft-800 to-mineshaft-900 md:w-60" > - SSH + + + SSH + - - {({ isActive }) => Hosts} - - - {(isAllowed) => - isAllowed && ( - - {({ isActive }) => ( - Certificate Authorities - )} - - ) - } - - - {({ isActive }) => Settings} + + + {({ isActive }) => ( + + + + + + Hosts + + + )} + + + {(isAllowed) => + isAllowed && ( + + {({ isActive }) => ( + + + + + + Certificates Authority + + + )} + + ) + } + + + + + + {({ isActive }) => ( + + + + + + Access Management + + + )} + + + {({ isActive }) => ( + + + + + + Settings + + + )} + + + + + + + + + + + } + > + Organization Home + + {assumedPrivilegeDetails && } diff --git a/frontend/src/pages/cert-manager/AlertingPage/components/PkiCollectionModal.tsx b/frontend/src/pages/cert-manager/AlertingPage/components/PkiCollectionModal.tsx index bca796fc9..366f51c62 100644 --- a/frontend/src/pages/cert-manager/AlertingPage/components/PkiCollectionModal.tsx +++ b/frontend/src/pages/cert-manager/AlertingPage/components/PkiCollectionModal.tsx @@ -82,7 +82,7 @@ export const PkiCollectionModal = ({ popUp, handlePopUpToggle }: Props) => { }); navigate({ - to: "/projects/$projectId/cert-manager/pki-collections/$collectionId", + to: "/projects/cert-management/$projectId/pki-collections/$collectionId", params: { projectId, collectionId diff --git a/frontend/src/pages/cert-manager/AlertingPage/components/PkiCollectionTable.tsx b/frontend/src/pages/cert-manager/AlertingPage/components/PkiCollectionTable.tsx index 1a6e613b6..ff525b1f4 100644 --- a/frontend/src/pages/cert-manager/AlertingPage/components/PkiCollectionTable.tsx +++ b/frontend/src/pages/cert-manager/AlertingPage/components/PkiCollectionTable.tsx @@ -21,7 +21,6 @@ import { } from "@app/components/v2"; import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context"; import { useListWorkspacePkiCollections } from "@app/hooks/api"; -import { ProjectType } from "@app/hooks/api/workspace/types"; import { UsePopUpState } from "@app/hooks/usePopUp"; type Props = { @@ -61,7 +60,7 @@ export const PkiCollectionTable = ({ handlePopUpOpen }: Props) => { key={`pki-collection-${pkiCollection.id}`} onClick={() => navigate({ - to: `/projects/$projectId/${ProjectType.CertificateManager}/pki-collections/$collectionId` as const, + to: "/projects/cert-management/$projectId/pki-collections/$collectionId", params: { projectId, collectionId: pkiCollection.id diff --git a/frontend/src/pages/cert-manager/AlertingPage/route.tsx b/frontend/src/pages/cert-manager/AlertingPage/route.tsx index 0b402699f..89f3b1888 100644 --- a/frontend/src/pages/cert-manager/AlertingPage/route.tsx +++ b/frontend/src/pages/cert-manager/AlertingPage/route.tsx @@ -3,7 +3,7 @@ import { createFileRoute } from "@tanstack/react-router"; import { AlertingPage } from "./AlertingPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/alerting" + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/alerting" )({ component: AlertingPage, beforeLoad: ({ context }) => { diff --git a/frontend/src/pages/cert-manager/CertAuthDetailsByIDPage/CertAuthDetailsByIDPage.tsx b/frontend/src/pages/cert-manager/CertAuthDetailsByIDPage/CertAuthDetailsByIDPage.tsx index 17a9fb8bf..0bf3c4431 100644 --- a/frontend/src/pages/cert-manager/CertAuthDetailsByIDPage/CertAuthDetailsByIDPage.tsx +++ b/frontend/src/pages/cert-manager/CertAuthDetailsByIDPage/CertAuthDetailsByIDPage.tsx @@ -18,7 +18,6 @@ import { ROUTE_PATHS } from "@app/const/routes"; import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context"; import { CaType, useDeleteCa, useGetCa } from "@app/hooks/api"; import { TInternalCertificateAuthority } from "@app/hooks/api/ca/types"; -import { ProjectType } from "@app/hooks/api/workspace/types"; import { usePopUp } from "@app/hooks/usePopUp"; import { CaInstallCertModal } from "../CertificateAuthoritiesPage/components/CaInstallCertModal"; @@ -71,7 +70,7 @@ const Page = () => { handlePopUpClose("deleteCa"); navigate({ - to: `/projects/$projectId/${ProjectType.CertificateManager}/certificate-authorities` as const, + to: "/projects/cert-management/$projectId/certificate-authorities", params: { projectId } diff --git a/frontend/src/pages/cert-manager/CertAuthDetailsByIDPage/route.tsx b/frontend/src/pages/cert-manager/CertAuthDetailsByIDPage/route.tsx index 8a374589e..bbe3e51d7 100644 --- a/frontend/src/pages/cert-manager/CertAuthDetailsByIDPage/route.tsx +++ b/frontend/src/pages/cert-manager/CertAuthDetailsByIDPage/route.tsx @@ -3,7 +3,7 @@ import { createFileRoute, linkOptions } from "@tanstack/react-router"; import { CertAuthDetailsByIDPage } from "./CertAuthDetailsByIDPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/ca/$caName" + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/ca/$caName" )({ component: CertAuthDetailsByIDPage, beforeLoad: ({ context, params }) => { @@ -13,7 +13,7 @@ export const Route = createFileRoute( { label: "Certificate Authorities", link: linkOptions({ - to: "/projects/$projectId/cert-manager/certificate-authorities", + to: "/projects/cert-management/$projectId/certificate-authorities", params: { projectId: params.projectId } diff --git a/frontend/src/pages/cert-manager/CertificateAuthoritiesPage/components/CaTable.tsx b/frontend/src/pages/cert-manager/CertificateAuthoritiesPage/components/CaTable.tsx index e0b91a239..00ab03625 100644 --- a/frontend/src/pages/cert-manager/CertificateAuthoritiesPage/components/CaTable.tsx +++ b/frontend/src/pages/cert-manager/CertificateAuthoritiesPage/components/CaTable.tsx @@ -30,7 +30,6 @@ import { getCaStatusBadgeVariant } from "@app/hooks/api/ca/constants"; import { TInternalCertificateAuthority } from "@app/hooks/api/ca/types"; -import { ProjectType } from "@app/hooks/api/workspace/types"; import { UsePopUpState } from "@app/hooks/usePopUp"; type Props = { @@ -79,7 +78,7 @@ export const CaTable = ({ handlePopUpOpen }: Props) => { key={`ca-${ca.id}`} onClick={() => navigate({ - to: `/projects/$projectId/${ProjectType.CertificateManager}/ca/$caName` as const, + to: "/projects/cert-management/$projectId/ca/$caName", params: { projectId: currentWorkspace.id, caName: ca.name diff --git a/frontend/src/pages/cert-manager/CertificateAuthoritiesPage/route.tsx b/frontend/src/pages/cert-manager/CertificateAuthoritiesPage/route.tsx index 36baa6e9e..b01369c07 100644 --- a/frontend/src/pages/cert-manager/CertificateAuthoritiesPage/route.tsx +++ b/frontend/src/pages/cert-manager/CertificateAuthoritiesPage/route.tsx @@ -3,7 +3,7 @@ import { createFileRoute } from "@tanstack/react-router"; import { CertificateAuthoritiesPage } from "./CertificateAuthoritiesPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificate-authorities" + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificate-authorities" )({ component: CertificateAuthoritiesPage, beforeLoad: ({ context }) => { diff --git a/frontend/src/pages/cert-manager/CertificatesPage/route.tsx b/frontend/src/pages/cert-manager/CertificatesPage/route.tsx index 7039f8770..68deb41b9 100644 --- a/frontend/src/pages/cert-manager/CertificatesPage/route.tsx +++ b/frontend/src/pages/cert-manager/CertificatesPage/route.tsx @@ -3,7 +3,7 @@ import { createFileRoute } from "@tanstack/react-router"; import { CertificatesPage } from "./CertificatesPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificates" + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificates" )({ component: CertificatesPage, beforeLoad: ({ context }) => { diff --git a/frontend/src/pages/cert-manager/PkiCollectionDetailsByIDPage/PkiCollectionDetailsByIDPage.tsx b/frontend/src/pages/cert-manager/PkiCollectionDetailsByIDPage/PkiCollectionDetailsByIDPage.tsx index 33c4808fd..0261d55fd 100644 --- a/frontend/src/pages/cert-manager/PkiCollectionDetailsByIDPage/PkiCollectionDetailsByIDPage.tsx +++ b/frontend/src/pages/cert-manager/PkiCollectionDetailsByIDPage/PkiCollectionDetailsByIDPage.tsx @@ -19,7 +19,6 @@ import { ROUTE_PATHS } from "@app/const/routes"; import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context"; import { useDeletePkiCollection, useGetPkiCollectionById } from "@app/hooks/api"; import { PkiItemType } from "@app/hooks/api/pkiCollections/constants"; -import { ProjectType } from "@app/hooks/api/workspace/types"; import { usePopUp } from "@app/hooks/usePopUp"; import { PkiCollectionModal } from "../AlertingPage/components/PkiCollectionModal"; @@ -57,7 +56,7 @@ export const PkiCollectionPage = () => { }); handlePopUpClose("deletePkiCollection"); navigate({ - to: `/projects/$projectId/${ProjectType.CertificateManager}/certificates` as const, + to: "/projects/cert-management/$projectId/certificates", params: { projectId } diff --git a/frontend/src/pages/cert-manager/PkiCollectionDetailsByIDPage/routes.tsx b/frontend/src/pages/cert-manager/PkiCollectionDetailsByIDPage/routes.tsx index ac29245e0..7fef38221 100644 --- a/frontend/src/pages/cert-manager/PkiCollectionDetailsByIDPage/routes.tsx +++ b/frontend/src/pages/cert-manager/PkiCollectionDetailsByIDPage/routes.tsx @@ -3,7 +3,7 @@ import { createFileRoute, linkOptions } from "@tanstack/react-router"; import { PkiCollectionDetailsByIDPage } from "./PkiCollectionDetailsByIDPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/pki-collections/$collectionId" + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/pki-collections/$collectionId" )({ component: PkiCollectionDetailsByIDPage, beforeLoad: ({ context, params }) => { @@ -13,7 +13,7 @@ export const Route = createFileRoute( { label: "Certificate Collections", link: linkOptions({ - to: "/projects/$projectId/cert-manager/certificates", + to: "/projects/cert-management/$projectId/certificates", params: { projectId: params.projectId } diff --git a/frontend/src/pages/cert-manager/PkiSubscriberDetailsByIDPage/PkiSubscriberDetailsByIDPage.tsx b/frontend/src/pages/cert-manager/PkiSubscriberDetailsByIDPage/PkiSubscriberDetailsByIDPage.tsx index 6f7e1362c..04db9861b 100644 --- a/frontend/src/pages/cert-manager/PkiSubscriberDetailsByIDPage/PkiSubscriberDetailsByIDPage.tsx +++ b/frontend/src/pages/cert-manager/PkiSubscriberDetailsByIDPage/PkiSubscriberDetailsByIDPage.tsx @@ -22,7 +22,6 @@ import { useWorkspace } from "@app/context"; import { useDeletePkiSubscriber, useGetPkiSubscriber } from "@app/hooks/api"; -import { ProjectType } from "@app/hooks/api/workspace/types"; import { usePopUp } from "@app/hooks/usePopUp"; import { PkiSubscriberModal } from "../PkiSubscribersPage/components/PkiSubscriberModal"; @@ -61,7 +60,7 @@ const Page = () => { handlePopUpClose("deletePkiSubscriber"); navigate({ - to: `/projects/$projectId/${ProjectType.CertificateManager}/subscribers` as const, + to: "/projects/cert-management/$projectId/subscribers", params: { projectId } diff --git a/frontend/src/pages/cert-manager/PkiSubscriberDetailsByIDPage/route.tsx b/frontend/src/pages/cert-manager/PkiSubscriberDetailsByIDPage/route.tsx index e9b0c7e7a..429a10574 100644 --- a/frontend/src/pages/cert-manager/PkiSubscriberDetailsByIDPage/route.tsx +++ b/frontend/src/pages/cert-manager/PkiSubscriberDetailsByIDPage/route.tsx @@ -3,7 +3,7 @@ import { createFileRoute, linkOptions } from "@tanstack/react-router"; import { PkiSubscriberDetailsByIDPage } from "./PkiSubscriberDetailsByIDPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/subscribers/$subscriberName" + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/subscribers/$subscriberName" )({ component: PkiSubscriberDetailsByIDPage, beforeLoad: ({ context, params }) => { @@ -13,7 +13,7 @@ export const Route = createFileRoute( { label: "Subscribers", link: linkOptions({ - to: "/projects/$projectId/cert-manager/subscribers", + to: "/projects/cert-management/$projectId/subscribers", params: { projectId: params.projectId } diff --git a/frontend/src/pages/cert-manager/PkiSubscribersPage/components/PkiSubscribersTable.tsx b/frontend/src/pages/cert-manager/PkiSubscribersPage/components/PkiSubscribersTable.tsx index eead0371a..d649c43a7 100644 --- a/frontend/src/pages/cert-manager/PkiSubscribersPage/components/PkiSubscribersTable.tsx +++ b/frontend/src/pages/cert-manager/PkiSubscribersPage/components/PkiSubscribersTable.tsx @@ -38,7 +38,6 @@ import { PkiSubscriberStatus, pkiSubscriberStatusToNameMap } from "@app/hooks/api/pkiSubscriber/constants"; -import { ProjectType } from "@app/hooks/api/workspace/types"; import { UsePopUpState } from "@app/hooks/usePopUp"; type Props = { @@ -76,7 +75,7 @@ export const PkiSubscribersTable = ({ handlePopUpOpen }: Props) => { key={`pki-subscriber-${subscriber.id}`} onClick={() => navigate({ - to: `/projects/$projectId/${ProjectType.CertificateManager}/subscribers/$subscriberName` as const, + to: "/projects/cert-management/$projectId/subscribers/$subscriberName", params: { projectId: currentWorkspace.id, subscriberName: subscriber.name diff --git a/frontend/src/pages/cert-manager/PkiSubscribersPage/route.tsx b/frontend/src/pages/cert-manager/PkiSubscribersPage/route.tsx index 58f906686..c8a2541d8 100644 --- a/frontend/src/pages/cert-manager/PkiSubscribersPage/route.tsx +++ b/frontend/src/pages/cert-manager/PkiSubscribersPage/route.tsx @@ -3,7 +3,7 @@ import { createFileRoute } from "@tanstack/react-router"; import { PkiSubscribersPage } from "./PkiSubscribersPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/subscribers/" + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/subscribers/" )({ component: PkiSubscribersPage, beforeLoad: ({ context }) => { diff --git a/frontend/src/pages/cert-manager/PkiTemplateListPage/route.tsx b/frontend/src/pages/cert-manager/PkiTemplateListPage/route.tsx index bc0fb5e04..cf568bf2c 100644 --- a/frontend/src/pages/cert-manager/PkiTemplateListPage/route.tsx +++ b/frontend/src/pages/cert-manager/PkiTemplateListPage/route.tsx @@ -3,7 +3,7 @@ import { createFileRoute } from "@tanstack/react-router"; import { PkiTemplateListPage } from "./PkiTemplateListPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificate-templates/" + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates/" )({ component: PkiTemplateListPage, beforeLoad: ({ context }) => { diff --git a/frontend/src/pages/cert-manager/SettingsPage/SettingsPage.tsx b/frontend/src/pages/cert-manager/SettingsPage/SettingsPage.tsx index 6c42e66dc..22c1a6961 100644 --- a/frontend/src/pages/cert-manager/SettingsPage/SettingsPage.tsx +++ b/frontend/src/pages/cert-manager/SettingsPage/SettingsPage.tsx @@ -2,12 +2,13 @@ import { Helmet } from "react-helmet"; import { useTranslation } from "react-i18next"; import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2"; +import { ProjectGeneralTab } from "@app/pages/project/SettingsPage/components/ProjectGeneralTab"; const tabs = [ { name: "General", key: "tab-project-general", - Component: () => Coming soon + Component: ProjectGeneralTab } ]; diff --git a/frontend/src/pages/cert-manager/SettingsPage/route.tsx b/frontend/src/pages/cert-manager/SettingsPage/route.tsx index dc8922092..f1400f30e 100644 --- a/frontend/src/pages/cert-manager/SettingsPage/route.tsx +++ b/frontend/src/pages/cert-manager/SettingsPage/route.tsx @@ -3,7 +3,7 @@ import { createFileRoute } from "@tanstack/react-router"; import { SettingsPage } from "./SettingsPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/settings" + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/settings" )({ component: SettingsPage, beforeLoad: ({ context }) => { diff --git a/frontend/src/pages/cert-manager/layout.tsx b/frontend/src/pages/cert-manager/layout.tsx index 48f3a88b3..6b846909e 100644 --- a/frontend/src/pages/cert-manager/layout.tsx +++ b/frontend/src/pages/cert-manager/layout.tsx @@ -1,9 +1,37 @@ import { createFileRoute } from "@tanstack/react-router"; +import { BreadcrumbTypes } from "@app/components/v2"; +import { workspaceKeys } from "@app/hooks/api"; +import { fetchUserProjectPermissions, roleQueryKeys } from "@app/hooks/api/roles/queries"; +import { fetchWorkspaceById } from "@app/hooks/api/workspace/queries"; import { PkiManagerLayout } from "@app/layouts/PkiManagerLayout"; +import { ProjectSelect } from "@app/layouts/ProjectLayout/components/ProjectSelect"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout" + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout" )({ - component: PkiManagerLayout + component: PkiManagerLayout, + beforeLoad: async ({ params, context }) => { + const project = await context.queryClient.ensureQueryData({ + queryKey: workspaceKeys.getWorkspaceById(params.projectId), + queryFn: () => fetchWorkspaceById(params.projectId) + }); + + await context.queryClient.ensureQueryData({ + queryKey: roleQueryKeys.getUserProjectPermissions({ + workspaceId: params.projectId + }), + queryFn: () => fetchUserProjectPermissions({ workspaceId: params.projectId }) + }); + + return { + project, + breadcrumbs: [ + { + type: BreadcrumbTypes.Component, + component: ProjectSelect + } + ] + }; + } }); diff --git a/frontend/src/pages/kms/KmipPage/route.tsx b/frontend/src/pages/kms/KmipPage/route.tsx index 520cae116..662bfc32c 100644 --- a/frontend/src/pages/kms/KmipPage/route.tsx +++ b/frontend/src/pages/kms/KmipPage/route.tsx @@ -3,7 +3,7 @@ import { createFileRoute } from "@tanstack/react-router"; import { KmipPage } from "./KmipPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout/kmip" + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/kmip" )({ component: KmipPage, beforeLoad: ({ context }) => { diff --git a/frontend/src/pages/kms/OverviewPage/route.tsx b/frontend/src/pages/kms/OverviewPage/route.tsx index b758782d7..8d4270a25 100644 --- a/frontend/src/pages/kms/OverviewPage/route.tsx +++ b/frontend/src/pages/kms/OverviewPage/route.tsx @@ -3,7 +3,7 @@ import { createFileRoute } from "@tanstack/react-router"; import { OverviewPage } from "./OverviewPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout/overview" + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/overview" )({ component: OverviewPage, beforeLoad: ({ context }) => { diff --git a/frontend/src/pages/kms/SettingsPage/SettingsPage.tsx b/frontend/src/pages/kms/SettingsPage/SettingsPage.tsx index 566107a77..cdc0582dc 100644 --- a/frontend/src/pages/kms/SettingsPage/SettingsPage.tsx +++ b/frontend/src/pages/kms/SettingsPage/SettingsPage.tsx @@ -2,12 +2,13 @@ import { Helmet } from "react-helmet"; import { useTranslation } from "react-i18next"; import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2"; +import { ProjectGeneralTab } from "@app/pages/project/SettingsPage/components/ProjectGeneralTab"; const tabs = [ { name: "General", key: "tab-project-general", - Component: () => Coming soon... + Component: ProjectGeneralTab } ]; diff --git a/frontend/src/pages/kms/SettingsPage/route.tsx b/frontend/src/pages/kms/SettingsPage/route.tsx index 8dd90bbdd..b47df3f86 100644 --- a/frontend/src/pages/kms/SettingsPage/route.tsx +++ b/frontend/src/pages/kms/SettingsPage/route.tsx @@ -3,7 +3,7 @@ import { createFileRoute } from "@tanstack/react-router"; import { SettingsPage } from "./SettingsPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout/settings" + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/settings" )({ component: SettingsPage, beforeLoad: ({ context }) => { diff --git a/frontend/src/pages/kms/layout.tsx b/frontend/src/pages/kms/layout.tsx index 48cdca4af..60bc35ab7 100644 --- a/frontend/src/pages/kms/layout.tsx +++ b/frontend/src/pages/kms/layout.tsx @@ -1,9 +1,37 @@ import { createFileRoute } from "@tanstack/react-router"; +import { BreadcrumbTypes } from "@app/components/v2"; +import { workspaceKeys } from "@app/hooks/api"; +import { fetchUserProjectPermissions, roleQueryKeys } from "@app/hooks/api/roles/queries"; +import { fetchWorkspaceById } from "@app/hooks/api/workspace/queries"; import { KmsLayout } from "@app/layouts/KmsLayout"; +import { ProjectSelect } from "@app/layouts/ProjectLayout/components/ProjectSelect"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout" + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout" )({ - component: KmsLayout + component: KmsLayout, + beforeLoad: async ({ params, context }) => { + const project = await context.queryClient.ensureQueryData({ + queryKey: workspaceKeys.getWorkspaceById(params.projectId), + queryFn: () => fetchWorkspaceById(params.projectId) + }); + + await context.queryClient.ensureQueryData({ + queryKey: roleQueryKeys.getUserProjectPermissions({ + workspaceId: params.projectId + }), + queryFn: () => fetchUserProjectPermissions({ workspaceId: params.projectId }) + }); + + return { + project, + breadcrumbs: [ + { + type: BreadcrumbTypes.Component, + component: ProjectSelect + } + ] + }; + } }); diff --git a/frontend/src/pages/organization/AdminPage/components/OrgAdminProjects/OrgAdminProjects.tsx b/frontend/src/pages/organization/AdminPage/components/OrgAdminProjects/OrgAdminProjects.tsx index 674018f14..5a9cac8bb 100644 --- a/frontend/src/pages/organization/AdminPage/components/OrgAdminProjects/OrgAdminProjects.tsx +++ b/frontend/src/pages/organization/AdminPage/components/OrgAdminProjects/OrgAdminProjects.tsx @@ -105,7 +105,7 @@ export const OrgAdminProjects = withPermission( {isProjectsLoading && } {!isProjectsLoading && - projects?.map(({ name, slug, createdAt, id, defaultProduct }) => ( + projects?.map(({ name, slug, createdAt, id, type }) => ( {name} {slug} @@ -126,7 +126,7 @@ export const OrgAdminProjects = withPermission( onClick={(e) => { e.stopPropagation(); e.preventDefault(); - handleAccessProject(defaultProduct, id); + handleAccessProject(type, id); }} icon={} disabled={ diff --git a/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/AppConnectionForm.tsx b/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/AppConnectionForm.tsx index 45a774780..b1181a68b 100644 --- a/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/AppConnectionForm.tsx +++ b/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/AppConnectionForm.tsx @@ -33,6 +33,7 @@ import { LdapConnectionForm } from "./LdapConnectionForm"; import { MsSqlConnectionForm } from "./MsSqlConnectionForm"; import { MySqlConnectionForm } from "./MySqlConnectionForm"; import { OCIConnectionForm } from "./OCIConnectionForm"; +import { OktaConnectionForm } from "./OktaConnectionForm"; import { OracleDBConnectionForm } from "./OracleDBConnectionForm"; import { PostgresConnectionForm } from "./PostgresConnectionForm"; import { RailwayConnectionForm } from "./RailwayConnectionForm"; @@ -149,6 +150,8 @@ const CreateForm = ({ app, onComplete }: CreateFormProps) => { return ; case AppConnection.Supabase: return ; + case AppConnection.Okta: + return ; default: throw new Error(`Unhandled App ${app}`); } @@ -253,6 +256,8 @@ const UpdateForm = ({ appConnection, onComplete }: UpdateFormProps) => { return ; case AppConnection.Supabase: return ; + case AppConnection.Okta: + return ; default: throw new Error(`Unhandled App ${(appConnection as TAppConnection).app}`); } diff --git a/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/GenericAppConnectionFields.tsx b/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/GenericAppConnectionFields.tsx index 70128025d..e7d9cf80c 100644 --- a/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/GenericAppConnectionFields.tsx +++ b/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/GenericAppConnectionFields.tsx @@ -6,7 +6,11 @@ import { slugSchema } from "@app/lib/schemas"; export const genericAppConnectionFieldsSchema = z.object({ name: slugSchema({ min: 1, max: 64, field: "Name" }), - description: z.string().trim().max(256, "Description cannot exceed 256 characters").nullish() + description: z.string().trim().max(256, "Description cannot exceed 256 characters").nullish(), + gatewayId: z + .string() + .nullish() + .transform((v) => (v === "" ? null : v)) }); export const GenericAppConnectionsFields = () => { diff --git a/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/MsSqlConnectionForm.tsx b/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/MsSqlConnectionForm.tsx index f7d48744d..0735a863c 100644 --- a/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/MsSqlConnectionForm.tsx +++ b/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/MsSqlConnectionForm.tsx @@ -1,10 +1,17 @@ import { useState } from "react"; import { Controller, FormProvider, useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; +import { useQuery } from "@tanstack/react-query"; import { z } from "zod"; -import { Button, FormControl, ModalClose, Select, SelectItem } from "@app/components/v2"; +import { OrgPermissionCan } from "@app/components/permissions"; +import { Button, FormControl, ModalClose, Select, SelectItem, Tooltip } from "@app/components/v2"; +import { + OrgGatewayPermissionActions, + OrgPermissionSubjects +} from "@app/context/OrgPermissionContext/types"; import { APP_CONNECTION_MAP, getAppConnectionMethodDetails } from "@app/helpers/appConnections"; +import { gatewaysQueryKeys } from "@app/hooks/api"; import { AppConnection } from "@app/hooks/api/appConnections/enums"; import { MsSqlConnectionMethod, @@ -51,6 +58,7 @@ export const MsSqlConnectionForm = ({ appConnection, onSubmit }: Props) => { defaultValues: appConnection ?? { app: AppConnection.MsSql, method: MsSqlConnectionMethod.UsernameAndPassword, + gatewayId: null, credentials: { host: "", port: 1433, @@ -71,6 +79,7 @@ export const MsSqlConnectionForm = ({ appConnection, onSubmit }: Props) => { } = form; const isPlatformManagedCredentials = appConnection?.isPlatformManagedCredentials ?? false; + const { data: gateways, isPending: isGatewaysLoading } = useQuery(gatewaysQueryKeys.list()); const confirmSubmit = async (formData: FormData) => { if (formData.isPlatformManagedCredentials) { @@ -90,6 +99,55 @@ export const MsSqlConnectionForm = ({ appConnection, onSubmit }: Props) => { }} > {!isUpdate && } + + {(isAllowed) => ( + ( + + + + + onChange(undefined)} + > + Internet Gateway + + {gateways?.map((el) => ( + + {el.name} + + ))} + + + + + )} + /> + )} + { defaultValues: appConnection ?? { app: AppConnection.MySql, method: MySqlConnectionMethod.UsernameAndPassword, + gatewayId: null, credentials: { host: "", port: 3306, @@ -68,6 +76,7 @@ export const MySqlConnectionForm = ({ appConnection, onSubmit }: Props) => { } = form; const isPlatformManagedCredentials = appConnection?.isPlatformManagedCredentials ?? false; + const { data: gateways, isPending: isGatewaysLoading } = useQuery(gatewaysQueryKeys.list()); const confirmSubmit = async (formData: FormData) => { if (formData.isPlatformManagedCredentials) { @@ -87,6 +96,55 @@ export const MySqlConnectionForm = ({ appConnection, onSubmit }: Props) => { }} > {!isUpdate && } + + {(isAllowed) => ( + ( + + + + + onChange(undefined)} + > + Internet Gateway + + {gateways?.map((el) => ( + + {el.name} + + ))} + + + + + )} + /> + )} + void; +}; + +const rootSchema = genericAppConnectionFieldsSchema.extend({ + app: z.literal(AppConnection.Okta) +}); + +const formSchema = z.discriminatedUnion("method", [ + rootSchema.extend({ + method: z.literal(OktaConnectionMethod.ApiToken), + credentials: z.object({ + instanceUrl: z + .string() + .trim() + .url("Invalid Instance URL") + .min(1, "Instance URL required") + .max(255), + apiToken: z + .string() + .trim() + .min(1, "API Token required") + .regex(/^00[a-zA-Z0-9_-]{40}$/, "Invalid Okta API Token format") + }) + }) +]); + +type FormData = z.infer; + +export const OktaConnectionForm = ({ appConnection, onSubmit }: Props) => { + const isUpdate = Boolean(appConnection); + + const form = useForm({ + resolver: zodResolver(formSchema), + defaultValues: appConnection ?? { + app: AppConnection.Okta, + method: OktaConnectionMethod.ApiToken + } + }); + + const { + handleSubmit, + control, + formState: { isSubmitting, isDirty } + } = form; + + return ( + + + {!isUpdate && } + ( + + onChange(val)} + className="w-full border border-mineshaft-500" + position="popper" + dropdownContainerClassName="max-w-none" + > + {Object.values(OktaConnectionMethod).map((method) => { + return ( + + {getAppConnectionMethodDetails(method).name}{" "} + + ); + })} + + + )} + /> + ( + + + + )} + /> + ( + + onChange(e.target.value)} + /> + + )} + /> + + + {isUpdate ? "Update Credentials" : "Connect to Okta"} + + + + Cancel + + + + + + ); +}; diff --git a/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/OracleDBConnectionForm.tsx b/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/OracleDBConnectionForm.tsx index 25dded675..87d4fe07b 100644 --- a/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/OracleDBConnectionForm.tsx +++ b/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/OracleDBConnectionForm.tsx @@ -1,10 +1,17 @@ import { useState } from "react"; import { Controller, FormProvider, useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; +import { useQuery } from "@tanstack/react-query"; import { z } from "zod"; -import { Button, FormControl, ModalClose, Select, SelectItem } from "@app/components/v2"; +import { OrgPermissionCan } from "@app/components/permissions"; +import { Button, FormControl, ModalClose, Select, SelectItem, Tooltip } from "@app/components/v2"; +import { + OrgGatewayPermissionActions, + OrgPermissionSubjects +} from "@app/context/OrgPermissionContext/types"; import { APP_CONNECTION_MAP, getAppConnectionMethodDetails } from "@app/helpers/appConnections"; +import { gatewaysQueryKeys } from "@app/hooks/api"; import { OracleDBConnectionMethod, TOracleDBConnection } from "@app/hooks/api/appConnections"; import { AppConnection } from "@app/hooks/api/appConnections/enums"; import { PlatformManagedConfirmationModal } from "@app/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/shared/PlatformManagedConfirmationModal"; @@ -48,6 +55,7 @@ export const OracleDBConnectionForm = ({ appConnection, onSubmit }: Props) => { defaultValues: appConnection ?? { app: AppConnection.OracleDB, method: OracleDBConnectionMethod.UsernameAndPassword, + gatewayId: null, credentials: { host: "", port: 1521, @@ -68,6 +76,7 @@ export const OracleDBConnectionForm = ({ appConnection, onSubmit }: Props) => { } = form; const isPlatformManagedCredentials = appConnection?.isPlatformManagedCredentials ?? false; + const { data: gateways, isPending: isGatewaysLoading } = useQuery(gatewaysQueryKeys.list()); const confirmSubmit = async (formData: FormData) => { if (formData.isPlatformManagedCredentials) { @@ -87,6 +96,55 @@ export const OracleDBConnectionForm = ({ appConnection, onSubmit }: Props) => { }} > {!isUpdate && } + + {(isAllowed) => ( + ( + + + + + onChange(undefined)} + > + Internet Gateway + + {gateways?.map((el) => ( + + {el.name} + + ))} + + + + + )} + /> + )} + { defaultValues: appConnection ?? { app: AppConnection.Postgres, method: PostgresConnectionMethod.UsernameAndPassword, + gatewayId: null, credentials: { host: "", port: 5432, @@ -68,6 +76,7 @@ export const PostgresConnectionForm = ({ appConnection, onSubmit }: Props) => { } = form; const isPlatformManagedCredentials = appConnection?.isPlatformManagedCredentials ?? false; + const { data: gateways, isPending: isGatewaysLoading } = useQuery(gatewaysQueryKeys.list()); const confirmSubmit = async (formData: FormData) => { if (formData.isPlatformManagedCredentials) { @@ -87,6 +96,55 @@ export const PostgresConnectionForm = ({ appConnection, onSubmit }: Props) => { }} > {!isUpdate && } + + {(isAllowed) => ( + ( + + + + + onChange(undefined)} + > + Internet Gateway + + {gateways?.map((el) => ( + + {el.name} + + ))} + + + + + )} + /> + )} + { title="Audit logs" description="Audit logs for security and compliance teams to monitor information access." /> - + diff --git a/frontend/src/pages/organization/AuditLogsPage/components/LogsDateFilter.tsx b/frontend/src/pages/organization/AuditLogsPage/components/LogsDateFilter.tsx index 87957ad22..71d418c9d 100644 --- a/frontend/src/pages/organization/AuditLogsPage/components/LogsDateFilter.tsx +++ b/frontend/src/pages/organization/AuditLogsPage/components/LogsDateFilter.tsx @@ -1,9 +1,8 @@ import { useState } from "react"; import { Controller, useForm } from "react-hook-form"; -import { faArrowRight, faCalendar, faChevronRight } from "@fortawesome/free-solid-svg-icons"; +import { faCalendar, faChevronRight } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { zodResolver } from "@hookform/resolvers/zod"; -import { format } from "date-fns"; import ms from "ms"; import { twMerge } from "tailwind-merge"; @@ -18,6 +17,7 @@ import { Select, SelectItem } from "@app/components/v2"; +import { formatDateTime, Timezone } from "@app/helpers/datetime"; import { auditLogDateFilterFormSchema, @@ -28,9 +28,19 @@ import { type Props = { setFilter: (data: TAuditLogDateFilterFormData) => void; filter: TAuditLogDateFilterFormData; + setTimezone: (timezone: Timezone) => void; + timezone: Timezone; }; const RELATIVE_VALUES = ["5m", "30m", "1h", "3h", "12h"]; -export const LogsDateFilter = ({ setFilter, filter }: Props) => { + +const RELATIVE_OPTIONS = [ + { label: "Minutes", unit: "m", values: [5, 10, 15, 30, 45] }, + { label: "Hours", unit: "h", values: [1, 2, 3, 6, 8, 12] }, + { label: "Days", unit: "d", values: [1, 2, 3, 4, 5, 6] }, + { label: "Weeks", unit: "w", values: [1, 2, 3, 4] } +]; + +export const LogsDateFilter = ({ setFilter, filter, timezone, setTimezone }: Props) => { const [isStartDatePickerOpen, setIsStartDatePickerOpen] = useState(false); const [isEndDatePickerOpen, setIsEndDatePickerOpen] = useState(false); const [isPopupOpen, setIsPopOpen] = useState(false); @@ -59,154 +69,258 @@ export const LogsDateFilter = ({ setFilter, filter }: Props) => { }; return ( - setIsPopOpen(el)}> - - {filter.type === AuditLogDateFilterType.Relative ? ( - <> - {RELATIVE_VALUES.map((el) => ( - - setFilter({ - relativeModeValue: el, - type: AuditLogDateFilterType.Relative, - endDate: new Date(), - startDate: new Date(Number(new Date()) - ms(el)) - }) - } - > - {el} - - ))} - > - ) : ( - <> - - {format(filter.startDate, "yyyy-MM-dd HH:mm")} - - - - - - {format(filter.endDate, "yyyy-MM-dd HH:mm")} - - > - )} - - - - {filter.type === AuditLogDateFilterType.Relative && isCustomRelative && ( - ({filter.relativeModeValue}) - )} - - - - - - ( - - field.onChange(el)} - className="w-full" + <> + setIsPopOpen(el)}> + + {filter.type === AuditLogDateFilterType.Relative ? ( + <> + {RELATIVE_VALUES.map((el) => ( + + setFilter({ + relativeModeValue: el, + type: AuditLogDateFilterType.Relative, + endDate: new Date(), + startDate: new Date(Number(new Date()) - ms(el)) + }) + } > - Relative - Absolute - - - )} - /> - {selectType === AuditLogDateFilterType.Relative && ( + {el} + + ))} + > + ) : ( + + + {formatDateTime({ + timezone, + timestamp: filter.startDate, + dateFormat: "yyyy/MM/dd HH:mm" + })} + + + + + + {formatDateTime({ + timezone, + timestamp: filter.endDate, + dateFormat: "yyyy/MM/dd HH:mm" + })} + + + )} + + + Custom + {filter.type === AuditLogDateFilterType.Relative && isCustomRelative && ( + ({filter.relativeModeValue}) + )} + + + + + ( - - - + + field.onChange(AuditLogDateFilterType.Absolute)} + variant="outline_bg" + className={twMerge( + "h-8 rounded-r-none font-normal", + field.value === AuditLogDateFilterType.Absolute && + "border-primary/40 bg-primary/[0.1]" + )} + > + Absolute + + field.onChange(AuditLogDateFilterType.Relative)} + variant="outline_bg" + className={twMerge( + "h-8 rounded-l-none font-normal", + field.value === AuditLogDateFilterType.Relative && + "border-primary/40 bg-primary/[0.1]" + )} + > + Relative + + )} /> - )} - {selectType === AuditLogDateFilterType.Absolute && ( - + {selectType === AuditLogDateFilterType.Relative && ( { + name="relativeModeValue" + render={({ field }) => { + const duration = field.value?.substring(0, field.value.length - 1); + const unitOfTime = field.value?.at(-1); return ( - - - + + {RELATIVE_OPTIONS.map(({ label, unit, values }) => ( + + {label} + {values.map((v) => { + const value = `${v}${unit}`; + return ( + field.onChange(value)} + className={twMerge( + "h-8 w-12", + field.value === value && "border-primary/40 bg-primary/[0.1]" + )} + > + {v} + + ); + })} + + ))} + + + field.onChange(`${val}${unitOfTime}`)} + max={60} + min={1} + /> + + + field.onChange(`${duration}${val}`)} + className="w-full" + position="popper" + > + {RELATIVE_OPTIONS.map((opt) => ( + {opt.label} + ))} + + + + ); }} /> - - - + )} + {selectType === AuditLogDateFilterType.Absolute && ( + + { + return ( + + + + ); + }} + /> + + { + return ( + + + + ); + }} + /> - { - return ( - - - - ); - }} - /> + )} + + + Apply + - )} - - - Apply - - - - - + + + + setTimezone(val as Timezone)} + className="w-[10.6rem] border !border-mineshaft-500 !bg-mineshaft-600 capitalize" + dropdownContainerClassName="max-w-none" + position="popper" + dropdownContainerStyle={{ + width: "100%" + }} + > + {Object.values(Timezone).map((tz) => ( + + {tz} Timezone + + ))} + + > ); }; diff --git a/frontend/src/pages/organization/AuditLogsPage/components/LogsFilter.tsx b/frontend/src/pages/organization/AuditLogsPage/components/LogsFilter.tsx index 73cc76ed7..572306973 100644 --- a/frontend/src/pages/organization/AuditLogsPage/components/LogsFilter.tsx +++ b/frontend/src/pages/organization/AuditLogsPage/components/LogsFilter.tsx @@ -300,10 +300,10 @@ export const LogsFilter = ({ presets, setFilter, filter }: Props) => { onChange(e); }} placeholder="All projects" - options={workspacesInOrg.map(({ name, id, defaultProduct }) => ({ + options={workspacesInOrg.map(({ name, id, type }) => ({ name, id, - type: defaultProduct + type }))} getOptionValue={(option) => option.id} getOptionLabel={(option) => option.name} diff --git a/frontend/src/pages/organization/AuditLogsPage/components/LogsSection.tsx b/frontend/src/pages/organization/AuditLogsPage/components/LogsSection.tsx index 7f676121f..d4d74659f 100644 --- a/frontend/src/pages/organization/AuditLogsPage/components/LogsSection.tsx +++ b/frontend/src/pages/organization/AuditLogsPage/components/LogsSection.tsx @@ -1,8 +1,11 @@ import { useEffect, useState } from "react"; +import { faArrowUpRightFromSquare, faBookOpen } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import ms from "ms"; import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal"; import { OrgPermissionActions, OrgPermissionSubjects, useSubscription } from "@app/context"; +import { Timezone } from "@app/helpers/datetime"; import { withPermission } from "@app/hoc"; import { usePopUp } from "@app/hooks/usePopUp"; @@ -20,10 +23,11 @@ type Props = { presets?: Presets; refetchInterval?: number; showFilters?: boolean; + pageView?: boolean; }; export const LogsSection = withPermission( - ({ presets, refetchInterval, showFilters = true }: Props) => { + ({ presets, refetchInterval, showFilters = true, pageView = false }: Props) => { const { subscription } = useSubscription(); const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp(["upgradePlan"] as const); @@ -31,6 +35,8 @@ export const LogsSection = withPermission( eventType: presets?.eventType || [], actor: presets?.actorId }); + const [timezone, setTimezone] = useState(Timezone.Local); + const [dateFilter, setDateFilter] = useState({ startDate: new Date(Number(new Date()) - ms("1h")), endDate: new Date(), @@ -43,10 +49,85 @@ export const LogsSection = withPermission( handlePopUpOpen("upgradePlan"); } }, [subscription]); + + if (pageView) + return ( + + + + + Audit History + + + + Docs + + + + + + + {showFilters && ( + + )} + {showFilters && ( + + )} + + + + + { + handlePopUpToggle("upgradePlan", isOpen); + }} + text="You can use audit logs if you switch to a paid Infisical plan." + /> + + + ); + return ( - {showFilters && } + {showFilters && ( + + )} {showFilters && ( )} @@ -67,6 +148,7 @@ export const LogsSection = withPermission( environment: logFilter?.environment?.slug, actor: logFilter?.actor }} + timezone={timezone} /> { +export const LogsTable = ({ filter, refetchInterval, timezone }: Props) => { // Determine the project ID for filtering const filterProjectId = // Use the projectId from the filter if it exists @@ -57,16 +57,7 @@ export const LogsTable = ({ filter, refetchInterval }: Props) => { - - Timestamp - - - - + Timestamp Event @@ -79,6 +70,7 @@ export const LogsTable = ({ filter, refetchInterval }: Props) => { rowNumber={index + i * AUDIT_LOG_LIMIT + 1} auditLog={auditLog} key={`audit-log-${auditLog.id}`} + timezone={timezone} /> ))} @@ -96,7 +88,7 @@ export const LogsTable = ({ filter, refetchInterval }: Props) => { {!isEmpty && ( { ); }; -export const LogsTableRow = ({ auditLog, rowNumber }: Props) => { +export const LogsTableRow = ({ auditLog, rowNumber, timezone }: Props) => { const [isOpen, setIsOpen] = useToggle(); return ( @@ -46,9 +47,7 @@ export const LogsTableRow = ({ auditLog, rowNumber }: Props) => { {rowNumber} - - {format(new Date(auditLog.createdAt), "MMM do yyyy, hh:mm a")} - + {formatDateTime({ timestamp: auditLog.createdAt, timezone })} diff --git a/frontend/src/pages/organization/IdentityDetailsByIDPage/components/IdentityProjectsSection/IdentityProjectRow.tsx b/frontend/src/pages/organization/IdentityDetailsByIDPage/components/IdentityProjectsSection/IdentityProjectRow.tsx index 8d8d45445..5b0aac0b7 100644 --- a/frontend/src/pages/organization/IdentityDetailsByIDPage/components/IdentityProjectsSection/IdentityProjectRow.tsx +++ b/frontend/src/pages/organization/IdentityDetailsByIDPage/components/IdentityProjectsSection/IdentityProjectRow.tsx @@ -6,6 +6,7 @@ import { format } from "date-fns"; import { createNotification } from "@app/components/notifications"; import { IconButton, Td, Tooltip, Tr } from "@app/components/v2"; +import { getProjectBaseURL } from "@app/helpers/project"; import { formatProjectRoleName } from "@app/helpers/roles"; import { useGetUserWorkspaces } from "@app/hooks/api"; import { IdentityMembership } from "@app/hooks/api/identities/types"; @@ -50,7 +51,7 @@ export const IdentityProjectRow = ({ onClick={() => { if (isAccessible) { navigate({ - to: "/projects/$projectId/access-management", + to: `${getProjectBaseURL(project.type)}/access-management` as const, params: { projectId: project.id }, diff --git a/frontend/src/pages/organization/ProjectsPage/components/AllProjectView.tsx b/frontend/src/pages/organization/ProjectsPage/components/AllProjectView.tsx index 3789cf024..52d8e5368 100644 --- a/frontend/src/pages/organization/ProjectsPage/components/AllProjectView.tsx +++ b/frontend/src/pages/organization/ProjectsPage/components/AllProjectView.tsx @@ -4,6 +4,7 @@ import { faArrowDownAZ, faBorderAll, faCheck, + faCheckCircle, faFolderOpen, faList, faMagnifyingGlass, @@ -16,10 +17,17 @@ import { twMerge } from "tailwind-merge"; import { createNotification } from "@app/components/notifications"; import { OrgPermissionCan } from "@app/components/permissions"; import { + Badge, Button, + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuTrigger, FormControl, IconButton, Input, + Lottie, Modal, ModalContent, Pagination, @@ -27,7 +35,7 @@ import { Tooltip } from "@app/components/v2"; import { OrgPermissionActions, OrgPermissionSubjects } from "@app/context"; -import { getProjectHomePage } from "@app/helpers/project"; +import { getProjectHomePage, getProjectLottieIcon, getProjectTitle } from "@app/helpers/project"; import { getUserTablePreference, PreferenceKey, @@ -35,7 +43,7 @@ import { } from "@app/helpers/userTablePreferences"; import { useDebounce, usePagination, usePopUp, useResetPageHelper } from "@app/hooks"; import { useRequestProjectAccess, useSearchProjects } from "@app/hooks/api"; -import { Workspace } from "@app/hooks/api/workspace/types"; +import { ProjectType, Workspace } from "@app/hooks/api/workspace/types"; type Props = { onAddNewProject: () => void; @@ -98,6 +106,7 @@ export const AllProjectView = ({ const navigate = useNavigate(); const [searchFilter, setSearchFilter] = useState(""); const [debouncedSearch] = useDebounce(searchFilter); + const [projectTypeFilter, setProjectTypeFilter] = useState(); const { setPage, perPage, @@ -124,7 +133,8 @@ export const AllProjectView = ({ limit, offset, name: debouncedSearch || undefined, - orderDirection + orderDirection, + type: projectTypeFilter }); useResetPageHelper({ @@ -134,6 +144,9 @@ export const AllProjectView = ({ }); const requestedWorkspaceDetails = (popUp.requestAccessConfirmation.data || {}) as Workspace; + const handleToggleFilterByProjectType = (el: ProjectType) => + setProjectTypeFilter((state) => (state === el ? undefined : el)); + return ( @@ -160,16 +173,62 @@ export const AllProjectView = ({ + + + + + + + + + + + + Filter By Project Type + {Object.values(ProjectType).map((el) => ( + { + e.preventDefault(); + handleToggleFilterByProjectType(el); + }} + icon={projectTypeFilter === el && } + iconPos="right" + > + + {getProjectTitle(el)} + + + ))} + + - - - + + + + + ( } onClick={() => { if (isAddingProjectsAllowed) { @@ -222,7 +281,7 @@ export const AllProjectView = ({ onKeyDown={(evt) => { if (evt.key === "Enter" && workspace.isMember) { navigate({ - to: getProjectHomePage(workspace.defaultProduct), + to: getProjectHomePage(workspace.type), params: { projectId: workspace.id } @@ -232,7 +291,7 @@ export const AllProjectView = ({ onClick={() => { if (workspace.isMember) { navigate({ - to: getProjectHomePage(workspace.defaultProduct), + to: getProjectHomePage(workspace.type), params: { projectId: workspace.id } @@ -241,38 +300,41 @@ export const AllProjectView = ({ }} key={workspace.id} className={twMerge( - "group flex min-w-72 grid-cols-6 items-center justify-center border-l border-r border-t border-mineshaft-600 bg-mineshaft-800 px-6 py-3 first:rounded-t-md", + "group flex min-w-72 items-center justify-center border-l border-r border-t border-mineshaft-600 bg-mineshaft-800 px-6 py-3 first:rounded-t-md", workspace.isMember ? "cursor-pointer hover:bg-mineshaft-700" : "cursor-default" )} > - - - - {workspace.name} - - - {workspace.isMember ? ( - - - Joined - - ) : ( - - handlePopUpOpen("requestAccessConfirmation", workspace)} - > - Request Access - - - )} - + + + - - {workspace.description} + + {workspace.name} + + {getProjectTitle(workspace.type)}{" "} + {workspace.description ? `- ${workspace.description}` : ""} + + {workspace.isMember ? ( + + + Joined + + ) : ( + + handlePopUpOpen("requestAccessConfirmation", workspace)} + > + Request Access + + + )} ))} diff --git a/frontend/src/pages/organization/ProjectsPage/components/MyProjectView.tsx b/frontend/src/pages/organization/ProjectsPage/components/MyProjectView.tsx index f9d2ed470..ea0d1d2ff 100644 --- a/frontend/src/pages/organization/ProjectsPage/components/MyProjectView.tsx +++ b/frontend/src/pages/organization/ProjectsPage/components/MyProjectView.tsx @@ -2,9 +2,9 @@ import { ReactNode, useMemo, useState } from "react"; import { faFolderOpen, faStar } from "@fortawesome/free-regular-svg-icons"; import { faArrowDownAZ, - faArrowRight, faArrowUpZA, faBorderAll, + faCheckCircle, faList, faMagnifyingGlass, faPlus, @@ -13,12 +13,26 @@ import { } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { useNavigate } from "@tanstack/react-router"; +import { twMerge } from "tailwind-merge"; import { createNotification } from "@app/components/notifications"; import { OrgPermissionCan } from "@app/components/permissions"; -import { Button, IconButton, Input, Pagination, Skeleton, Tooltip } from "@app/components/v2"; +import { + Button, + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuTrigger, + IconButton, + Input, + Lottie, + Pagination, + Skeleton, + Tooltip +} from "@app/components/v2"; import { OrgPermissionActions, OrgPermissionSubjects, useOrganization } from "@app/context"; -import { getProjectHomePage } from "@app/helpers/project"; +import { getProjectHomePage, getProjectLottieIcon, getProjectTitle } from "@app/helpers/project"; import { getUserTablePreference, PreferenceKey, @@ -29,7 +43,7 @@ import { useGetUserWorkspaces } from "@app/hooks/api"; import { OrderByDirection } from "@app/hooks/api/generic/types"; import { useUpdateUserProjectFavorites } from "@app/hooks/api/users/mutation"; import { useGetUserProjectFavorites } from "@app/hooks/api/users/queries"; -import { Workspace } from "@app/hooks/api/workspace/types"; +import { ProjectType, Workspace } from "@app/hooks/api/workspace/types"; type Props = { onAddNewProject: () => void; @@ -53,6 +67,9 @@ export const MyProjectView = ({ }: Props) => { const navigate = useNavigate(); const { currentOrg } = useOrganization(); + const [projectTypeFilter, setProjectTypeFilter] = useState>>( + {} + ); const { data: workspaces = [], isPending: isWorkspaceLoading } = useGetUserWorkspaces(); const { @@ -67,6 +84,7 @@ export const MyProjectView = ({ } = usePagination(ProjectOrderBy.Name, { initPerPage: getUserTablePreference("myProjectsTable", PreferenceKey.PerPage, 24) }); + const isTableFilteredByType = Boolean(Object.values(projectTypeFilter).some((el) => el)); const handlePerPageChange = (newPerPage: number) => { setPerPage(newPerPage); @@ -88,13 +106,18 @@ export const MyProjectView = ({ const filteredWorkspaces = useMemo( () => workspaces - .filter((ws) => ws?.name?.toLowerCase().includes(searchFilter.toLowerCase())) + .filter((ws) => { + if (isTableFilteredByType && !projectTypeFilter?.[ws.type]) { + return false; + } + return ws?.name?.toLowerCase().includes(searchFilter.toLowerCase()); + }) .sort((a, b) => orderDirection === OrderByDirection.ASC ? a.name.toLowerCase().localeCompare(b.name.toLowerCase()) : b.name.toLowerCase().localeCompare(a.name.toLowerCase()) ), - [searchFilter, orderDirection, workspaces] + [searchFilter, orderDirection, workspaces, projectTypeFilter] ); useResetPageHelper({ @@ -117,6 +140,15 @@ export const MyProjectView = ({ }; }, [filteredWorkspaces, projectFavorites, offset, limit, page]); + const handleToggleFilterByProjectType = (type: ProjectType) => { + setProjectTypeFilter((state) => { + return { + ...(state || {}), + [type]: !state?.[type] + }; + }); + }; + const addProjectToFavorites = async (projectId: string) => { try { if (currentOrg?.id) { @@ -153,61 +185,53 @@ export const MyProjectView = ({ { navigate({ - to: getProjectHomePage(workspace.defaultProduct), + to: getProjectHomePage(workspace.type), params: { projectId: workspace.id } }); }} key={workspace.id} - className="flex h-40 min-w-72 cursor-pointer flex-col rounded-md border border-mineshaft-600 bg-mineshaft-800 p-4" + className="cursor-pointer overflow-clip rounded border border-l-[4px] border-mineshaft-600 border-l-mineshaft-400 bg-mineshaft-800 p-4 transition-transform duration-100 hover:scale-[103%] hover:border-l-primary hover:bg-mineshaft-700" > - - {workspace.name} - {isFavorite ? ( - { - e.stopPropagation(); - removeProjectFromFavorites(workspace.id); - }} + + + - ) : ( - { - e.stopPropagation(); - addProjectToFavorites(workspace.id); - }} - /> - )} - - - - {workspace.description} - - - - - - Explore{" "} + + + {workspace.name} + + {getProjectTitle(workspace.type)} + + + + {isFavorite ? ( { + e.stopPropagation(); + removeProjectFromFavorites(workspace.id); + }} /> - - + ) : ( + { + e.stopPropagation(); + addProjectToFavorites(workspace.id); + }} + /> + )} + + + {workspace.description || "No description"} + ); const renderProjectListItem = (workspace: Workspace, isFavorite: boolean, index: number) => ( @@ -215,21 +239,33 @@ export const MyProjectView = ({ { navigate({ - to: getProjectHomePage(workspace.defaultProduct), + to: getProjectHomePage(workspace.type), params: { projectId: workspace.id } }); }} key={workspace.id} - className={`group grid h-14 min-w-72 cursor-pointer grid-cols-6 border-l border-r border-t border-mineshaft-600 bg-mineshaft-800 px-6 hover:bg-mineshaft-700 ${ + className={`group flex min-w-72 cursor-pointer border-l border-r border-t border-mineshaft-600 bg-mineshaft-800 px-6 py-3 hover:bg-mineshaft-700 ${ index === 0 && "rounded-t-md" }`} > - - {workspace.name} + + + + + + {workspace.name} + + {getProjectTitle(workspace.type)}{" "} + {workspace.description ? `- ${workspace.description}` : ""} + + - + {isFavorite ? ( + {isProjectViewLoading && Array.apply(0, Array(3)).map((_x, i) => ( No projects match search... ); + } else if (filteredWorkspaces.length === 0 && isTableFilteredByType) { + projectsComponents = ( + + + No projects match filters... + + ); } + return ( @@ -351,6 +398,49 @@ export const MyProjectView = ({ + + + + + + + + + + + + Filter By Project Type + {Object.values(ProjectType).map((el) => ( + { + e.preventDefault(); + handleToggleFilterByProjectType(el); + }} + icon={projectTypeFilter?.[el] && } + iconPos="right" + > + + {getProjectTitle(el)} + + + ))} + + ( } onClick={() => { if (isAddingProjectsAllowed) { @@ -417,7 +507,7 @@ export const MyProjectView = ({ onChangePerPage={handlePerPageChange} /> )} - {isWorkspaceEmpty && ( + {isWorkspaceEmpty && !isTableFilteredByType && ( { value={value} onValueChange={onChange} className="absolute left-0 top-0 h-full w-full cursor-pointer opacity-0" - dropdownContainerClassName="mt-10 ml-5" + position="popper" > My Projects All Projects diff --git a/frontend/src/pages/organization/SettingsPage/components/ProjectTemplatesTab/components/EditProjectTemplateSection/EditProjectTemplateSection.tsx b/frontend/src/pages/organization/SettingsPage/components/ProjectTemplatesTab/components/EditProjectTemplateSection/EditProjectTemplateSection.tsx index 60ca359bb..439f71718 100644 --- a/frontend/src/pages/organization/SettingsPage/components/ProjectTemplatesTab/components/EditProjectTemplateSection/EditProjectTemplateSection.tsx +++ b/frontend/src/pages/organization/SettingsPage/components/ProjectTemplatesTab/components/EditProjectTemplateSection/EditProjectTemplateSection.tsx @@ -24,6 +24,7 @@ export const EditProjectTemplateSection = ({ template, onBack }: Props) => { initialData: template, enabled: !isInfisicalTemplate }); + const finalTemplate = isInfisicalTemplate ? template : projectTemplate; return ( @@ -41,10 +42,10 @@ export const EditProjectTemplateSection = ({ template, onBack }: Props) => { - ) : projectTemplate ? ( + ) : finalTemplate ? ( ) : ( diff --git a/frontend/src/pages/organization/SettingsPage/components/ProjectTemplatesTab/components/EditProjectTemplateSection/components/EditProjectTemplate.tsx b/frontend/src/pages/organization/SettingsPage/components/ProjectTemplatesTab/components/EditProjectTemplateSection/components/EditProjectTemplate.tsx index 50be108bc..c3ecdfa79 100644 --- a/frontend/src/pages/organization/SettingsPage/components/ProjectTemplatesTab/components/EditProjectTemplateSection/components/EditProjectTemplate.tsx +++ b/frontend/src/pages/organization/SettingsPage/components/ProjectTemplatesTab/components/EditProjectTemplateSection/components/EditProjectTemplate.tsx @@ -5,8 +5,10 @@ import { createNotification } from "@app/components/notifications"; import { OrgPermissionCan } from "@app/components/permissions"; import { Button, DeleteActionModal } from "@app/components/v2"; import { OrgPermissionActions, OrgPermissionSubjects } from "@app/context"; +import { getProjectTitle } from "@app/helpers/project"; import { usePopUp } from "@app/hooks"; import { TProjectTemplate, useDeleteProjectTemplate } from "@app/hooks/api/projectTemplates"; +import { ProjectType } from "@app/hooks/api/workspace/types"; import { ProjectTemplateDetailsModal } from "../../ProjectTemplateDetailsModal"; import { ProjectTemplateEnvironmentsForm } from "./ProjectTemplateEnvironmentsForm"; @@ -24,7 +26,7 @@ export const EditProjectTemplate = ({ isInfisicalTemplate, projectTemplate, onBa "editDetails" ] as const); - const { id: templateId, name, description } = projectTemplate; + const { id: templateId, name, description, type } = projectTemplate; const deleteProjectTemplate = useDeleteProjectTemplate(); @@ -53,7 +55,10 @@ export const EditProjectTemplate = ({ isInfisicalTemplate, projectTemplate, onBa {name} - {description || "Project Template"} + + {`${getProjectTitle(type)} - `} + {description || "Project Template"} + {!isInfisicalTemplate && ( @@ -94,10 +99,12 @@ export const EditProjectTemplate = ({ isInfisicalTemplate, projectTemplate, onBa )} - + {type === ProjectType.SecretManager && ( + + )} Save - + )} diff --git a/frontend/src/pages/organization/SettingsPage/components/ProjectTemplatesTab/components/ProjectTemplateDetailsModal.tsx b/frontend/src/pages/organization/SettingsPage/components/ProjectTemplatesTab/components/ProjectTemplateDetailsModal.tsx index 604a37d6d..bb3a03fc1 100644 --- a/frontend/src/pages/organization/SettingsPage/components/ProjectTemplatesTab/components/ProjectTemplateDetailsModal.tsx +++ b/frontend/src/pages/organization/SettingsPage/components/ProjectTemplatesTab/components/ProjectTemplateDetailsModal.tsx @@ -1,5 +1,6 @@ -import { useForm } from "react-hook-form"; +import { Controller, useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; +import { twMerge } from "tailwind-merge"; import { z } from "zod"; import { createNotification } from "@app/components/notifications"; @@ -7,21 +8,25 @@ import { Button, FormControl, Input, + Lottie, Modal, ModalClose, ModalContent, TextArea } from "@app/components/v2"; +import { getProjectLottieIcon } from "@app/helpers/project"; import { TProjectTemplate, useCreateProjectTemplate, useUpdateProjectTemplate } from "@app/hooks/api/projectTemplates"; +import { ProjectType } from "@app/hooks/api/workspace/types"; import { slugSchema } from "@app/lib/schemas"; const formSchema = z.object({ name: slugSchema({ min: 1, max: 64, field: "Name" }), - description: z.string().max(500).optional() + description: z.string().max(500).optional(), + type: z.nativeEnum(ProjectType).optional() }); export type FormData = z.infer; @@ -38,6 +43,29 @@ type FormProps = { onComplete: (template: TProjectTemplate) => void; }; +const PROJECT_TYPE_MENU_ITEMS = [ + { + label: "Secrets Manager", + value: ProjectType.SecretManager + }, + { + label: "Certificates Manager", + value: ProjectType.CertificateManager + }, + { + label: "KMS", + value: ProjectType.KMS + }, + { + label: "SSH", + value: ProjectType.SSH + }, + { + label: "Secret Scanning", + value: ProjectType.SecretScanning + } +]; + const ProjectTemplateForm = ({ onComplete, projectTemplate }: FormProps) => { const createProjectTemplate = useCreateProjectTemplate(); const updateProjectTemplate = useUpdateProjectTemplate(); @@ -45,12 +73,14 @@ const ProjectTemplateForm = ({ onComplete, projectTemplate }: FormProps) => { const { handleSubmit, register, + control, formState: { isSubmitting, errors } } = useForm({ resolver: zodResolver(formSchema), defaultValues: { name: projectTemplate?.name, - description: projectTemplate?.description + description: projectTemplate?.description, + type: ProjectType.SecretManager } }); @@ -90,6 +120,42 @@ const ProjectTemplateForm = ({ onComplete, projectTemplate }: FormProps) => { > + ( + + + {PROJECT_TYPE_MENU_ITEMS.map((el) => ( + field.onChange(el.value)} + role="button" + tabIndex={0} + onKeyDown={(e) => { + if (e.key === "Enter") { + field.onChange(el.value); + } + }} + > + + {el.label} + + ))} + + + )} + /> { Name + Type Roles - Environments @@ -80,7 +81,7 @@ export const ProjectTemplatesTable = ({ onEdit }: Props) => { /> )} {filteredTemplates.map((template) => { - const { id, name, roles, environments = [], description } = template; + const { id, name, roles, description, type } = template; return ( onEdit(template)} @@ -99,6 +100,7 @@ export const ProjectTemplatesTable = ({ onEdit }: Props) => { )} + {getProjectTitle(type)} {roles.length} {roles.length > 0 && ( @@ -119,26 +121,6 @@ export const ProjectTemplatesTable = ({ onEdit }: Props) => { )} - - {environments?.length || 0} - {environments?.length && ( - - {environments - ?.sort((a, b) => (a.position > b.position ? 1 : -1)) - .map((env) => {env.name})} - - } - > - - - )} - {name !== "default" && ( { if (isAccessible) { navigate({ - to: "/projects/$projectId/access-management", + to: `${getProjectBaseURL(project.type)}/access-management` as const, params: { projectId: project.id }, diff --git a/frontend/src/pages/project/AccessControlPage/AccessControlPage.tsx b/frontend/src/pages/project/AccessControlPage/AccessControlPage.tsx index 096514b69..8bb007e88 100644 --- a/frontend/src/pages/project/AccessControlPage/AccessControlPage.tsx +++ b/frontend/src/pages/project/AccessControlPage/AccessControlPage.tsx @@ -4,6 +4,8 @@ import { useNavigate, useSearch } from "@tanstack/react-router"; import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2"; import { useWorkspace } from "@app/context"; +import { getProjectBaseURL } from "@app/helpers/project"; +import { ProjectType } from "@app/hooks/api/workspace/types"; import { ProjectAccessControlTabs } from "@app/types/project"; import { @@ -24,7 +26,7 @@ const Page = () => { const updateSelectedTab = (tab: string) => { navigate({ - to: "/projects/$projectId/access-management", + to: `${getProjectBaseURL(currentWorkspace.type)}/access-management` as const, search: (prev) => ({ ...prev, selectedTab: tab }), params: { projectId: currentWorkspace.id @@ -32,6 +34,8 @@ const Page = () => { }); }; + const isSecretManager = currentWorkspace.type === ProjectType.SecretManager; + return ( @@ -48,7 +52,9 @@ const Page = () => { Machine Identities - Service Tokens + {isSecretManager && ( + Service Tokens + )} Project Roles @@ -60,9 +66,11 @@ const Page = () => { - - - + {isSecretManager && ( + + + + )} diff --git a/frontend/src/pages/project/AccessControlPage/components/GroupsTab/components/GroupsSection/GroupsTable.tsx b/frontend/src/pages/project/AccessControlPage/components/GroupsTab/components/GroupsSection/GroupsTable.tsx index 37816ceb9..9bd98084e 100644 --- a/frontend/src/pages/project/AccessControlPage/components/GroupsTab/components/GroupsSection/GroupsTable.tsx +++ b/frontend/src/pages/project/AccessControlPage/components/GroupsTab/components/GroupsSection/GroupsTable.tsx @@ -33,6 +33,7 @@ import { Tr } from "@app/components/v2"; import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context"; +import { getProjectBaseURL } from "@app/helpers/project"; import { getUserTablePreference, PreferenceKey, @@ -158,7 +159,7 @@ export const GroupTable = ({ handlePopUpOpen }: Props) => { onKeyDown={(evt) => { if (evt.key === "Enter") { navigate({ - to: "/projects/$projectId/groups/$groupId", + to: `${getProjectBaseURL(currentWorkspace.type)}/groups/$groupId` as const, params: { projectId: currentWorkspace.id, groupId: id @@ -168,7 +169,7 @@ export const GroupTable = ({ handlePopUpOpen }: Props) => { }} onClick={() => navigate({ - to: "/projects/$projectId/groups/$groupId", + to: `${getProjectBaseURL(currentWorkspace.type)}/groups/$groupId` as const, params: { projectId: currentWorkspace.id, groupId: id diff --git a/frontend/src/pages/project/AccessControlPage/components/IdentityTab/IdentityTab.tsx b/frontend/src/pages/project/AccessControlPage/components/IdentityTab/IdentityTab.tsx index 52ac3b349..5b6e773db 100644 --- a/frontend/src/pages/project/AccessControlPage/components/IdentityTab/IdentityTab.tsx +++ b/frontend/src/pages/project/AccessControlPage/components/IdentityTab/IdentityTab.tsx @@ -46,6 +46,7 @@ import { Tr } from "@app/components/v2"; import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context"; +import { getProjectBaseURL } from "@app/helpers/project"; import { formatProjectRoleName } from "@app/helpers/roles"; import { getUserTablePreference, @@ -260,7 +261,7 @@ export const IdentityTab = withProjectPermission( onKeyDown={(evt) => { if (evt.key === "Enter") { navigate({ - to: "/projects/$projectId/identities/$identityId", + to: `${getProjectBaseURL(currentWorkspace.type)}/identities/$identityId` as const, params: { projectId: currentWorkspace.id, identityId: id @@ -270,7 +271,7 @@ export const IdentityTab = withProjectPermission( }} onClick={() => navigate({ - to: "/projects/$projectId/identities/$identityId", + to: `${getProjectBaseURL(currentWorkspace.type)}/identities/$identityId` as const, params: { projectId: currentWorkspace.id, identityId: id diff --git a/frontend/src/pages/project/AccessControlPage/components/MembersTab/components/MemberRoleForm/MemberRoleForm.tsx b/frontend/src/pages/project/AccessControlPage/components/MembersTab/components/MemberRoleForm/MemberRoleForm.tsx index ba4e0fac4..735257293 100644 --- a/frontend/src/pages/project/AccessControlPage/components/MembersTab/components/MemberRoleForm/MemberRoleForm.tsx +++ b/frontend/src/pages/project/AccessControlPage/components/MembersTab/components/MemberRoleForm/MemberRoleForm.tsx @@ -2,6 +2,7 @@ import { Link } from "@tanstack/react-router"; import { Alert, AlertDescription } from "@app/components/v2"; import { useWorkspace } from "@app/context"; +import { getProjectBaseURL } from "@app/helpers/project"; import { TWorkspaceUser } from "@app/hooks/api/types"; import { MemberRbacSection } from "./MemberRbacSection"; @@ -21,7 +22,7 @@ export const MemberRoleForm = ({ projectMember, onOpenUpgradeModal }: Props) => > { onKeyDown={(evt) => { if (evt.key === "Enter") { navigate({ - to: "/projects/$projectId/members/$membershipId", + to: `${getProjectBaseURL(currentWorkspace.type)}/members/$membershipId`, params: { projectId: workspaceId, membershipId @@ -321,7 +322,7 @@ export const MembersTable = ({ handlePopUpOpen }: Props) => { }} onClick={() => navigate({ - to: "/projects/$projectId/members/$membershipId", + to: `${getProjectBaseURL(currentWorkspace.type)}/members/$membershipId`, params: { projectId: workspaceId, membershipId diff --git a/frontend/src/pages/project/AccessControlPage/components/ProjectRoleListTab/components/ProjectRoleList/ProjectRoleList.tsx b/frontend/src/pages/project/AccessControlPage/components/ProjectRoleListTab/components/ProjectRoleList/ProjectRoleList.tsx index 2a01764b0..211f1d0e8 100644 --- a/frontend/src/pages/project/AccessControlPage/components/ProjectRoleListTab/components/ProjectRoleList/ProjectRoleList.tsx +++ b/frontend/src/pages/project/AccessControlPage/components/ProjectRoleListTab/components/ProjectRoleList/ProjectRoleList.tsx @@ -40,6 +40,7 @@ import { Tr } from "@app/components/v2"; import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context"; +import { getProjectBaseURL } from "@app/helpers/project"; import { isCustomProjectRole } from "@app/helpers/roles"; import { getUserTablePreference, @@ -249,7 +250,7 @@ export const ProjectRoleList = () => { className="h-10 cursor-pointer transition-colors duration-100 hover:bg-mineshaft-700" onClick={() => navigate({ - to: "/projects/$projectId/roles/$roleSlug", + to: `${getProjectBaseURL(currentWorkspace.type)}/roles/$roleSlug`, params: { projectId: currentWorkspace.id, roleSlug: slug @@ -291,7 +292,7 @@ export const ProjectRoleList = () => { onClick={(e) => { e.stopPropagation(); navigate({ - to: "/projects/$projectId/roles/$roleSlug", + to: `${getProjectBaseURL(currentWorkspace.type)}/roles/$roleSlug`, params: { projectId: currentWorkspace.id, roleSlug: slug diff --git a/frontend/src/pages/project/AccessControlPage/route-cert-manager.tsx b/frontend/src/pages/project/AccessControlPage/route-cert-manager.tsx new file mode 100644 index 000000000..e5549b5be --- /dev/null +++ b/frontend/src/pages/project/AccessControlPage/route-cert-manager.tsx @@ -0,0 +1,32 @@ +import { createFileRoute, stripSearchParams } from "@tanstack/react-router"; +import { zodValidator } from "@tanstack/zod-adapter"; +import { z } from "zod"; + +import { ProjectAccessControlTabs } from "@app/types/project"; + +import { AccessControlPage } from "./AccessControlPage"; + +const AccessControlPageQuerySchema = z.object({ + selectedTab: z.nativeEnum(ProjectAccessControlTabs).catch(ProjectAccessControlTabs.Member), + requesterEmail: z.string().catch("") +}); + +export const Route = createFileRoute( + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/access-management" +)({ + component: AccessControlPage, + validateSearch: zodValidator(AccessControlPageQuerySchema), + search: { + middlewares: [stripSearchParams({ requesterEmail: "" })] + }, + beforeLoad: ({ context }) => { + return { + breadcrumbs: [ + ...context.breadcrumbs, + { + label: "Access Control" + } + ] + }; + } +}); diff --git a/frontend/src/pages/project/AccessControlPage/route-kms.tsx b/frontend/src/pages/project/AccessControlPage/route-kms.tsx new file mode 100644 index 000000000..0968565c4 --- /dev/null +++ b/frontend/src/pages/project/AccessControlPage/route-kms.tsx @@ -0,0 +1,32 @@ +import { createFileRoute, stripSearchParams } from "@tanstack/react-router"; +import { zodValidator } from "@tanstack/zod-adapter"; +import { z } from "zod"; + +import { ProjectAccessControlTabs } from "@app/types/project"; + +import { AccessControlPage } from "./AccessControlPage"; + +const AccessControlPageQuerySchema = z.object({ + selectedTab: z.nativeEnum(ProjectAccessControlTabs).catch(ProjectAccessControlTabs.Member), + requesterEmail: z.string().catch("") +}); + +export const Route = createFileRoute( + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/access-management" +)({ + component: AccessControlPage, + validateSearch: zodValidator(AccessControlPageQuerySchema), + search: { + middlewares: [stripSearchParams({ requesterEmail: "" })] + }, + beforeLoad: ({ context }) => { + return { + breadcrumbs: [ + ...context.breadcrumbs, + { + label: "Access Control" + } + ] + }; + } +}); diff --git a/frontend/src/pages/project/AccessControlPage/route-secret-manager.tsx b/frontend/src/pages/project/AccessControlPage/route-secret-manager.tsx new file mode 100644 index 000000000..efdb9f9b2 --- /dev/null +++ b/frontend/src/pages/project/AccessControlPage/route-secret-manager.tsx @@ -0,0 +1,32 @@ +import { createFileRoute, stripSearchParams } from "@tanstack/react-router"; +import { zodValidator } from "@tanstack/zod-adapter"; +import { z } from "zod"; + +import { ProjectAccessControlTabs } from "@app/types/project"; + +import { AccessControlPage } from "./AccessControlPage"; + +const AccessControlPageQuerySchema = z.object({ + selectedTab: z.nativeEnum(ProjectAccessControlTabs).catch(ProjectAccessControlTabs.Member), + requesterEmail: z.string().catch("") +}); + +export const Route = createFileRoute( + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/access-management" +)({ + component: AccessControlPage, + validateSearch: zodValidator(AccessControlPageQuerySchema), + search: { + middlewares: [stripSearchParams({ requesterEmail: "" })] + }, + beforeLoad: ({ context }) => { + return { + breadcrumbs: [ + ...context.breadcrumbs, + { + label: "Access Control" + } + ] + }; + } +}); diff --git a/frontend/src/pages/project/AccessControlPage/route.tsx b/frontend/src/pages/project/AccessControlPage/route-secret-scanning.tsx similarity index 86% rename from frontend/src/pages/project/AccessControlPage/route.tsx rename to frontend/src/pages/project/AccessControlPage/route-secret-scanning.tsx index 4b51fdecb..2305a761c 100644 --- a/frontend/src/pages/project/AccessControlPage/route.tsx +++ b/frontend/src/pages/project/AccessControlPage/route-secret-scanning.tsx @@ -12,7 +12,7 @@ const AccessControlPageQuerySchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/access-management" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/access-management" )({ component: AccessControlPage, validateSearch: zodValidator(AccessControlPageQuerySchema), diff --git a/frontend/src/pages/project/AccessControlPage/route-ssh.tsx b/frontend/src/pages/project/AccessControlPage/route-ssh.tsx new file mode 100644 index 000000000..d4cc6f11e --- /dev/null +++ b/frontend/src/pages/project/AccessControlPage/route-ssh.tsx @@ -0,0 +1,32 @@ +import { createFileRoute, stripSearchParams } from "@tanstack/react-router"; +import { zodValidator } from "@tanstack/zod-adapter"; +import { z } from "zod"; + +import { ProjectAccessControlTabs } from "@app/types/project"; + +import { AccessControlPage } from "./AccessControlPage"; + +const AccessControlPageQuerySchema = z.object({ + selectedTab: z.nativeEnum(ProjectAccessControlTabs).catch(ProjectAccessControlTabs.Member), + requesterEmail: z.string().catch("") +}); + +export const Route = createFileRoute( + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/access-management" +)({ + component: AccessControlPage, + validateSearch: zodValidator(AccessControlPageQuerySchema), + search: { + middlewares: [stripSearchParams({ requesterEmail: "" })] + }, + beforeLoad: ({ context }) => { + return { + breadcrumbs: [ + ...context.breadcrumbs, + { + label: "Access Control" + } + ] + }; + } +}); diff --git a/frontend/src/pages/project/GroupDetailsByIDPage/components/GroupDetailsSection.tsx b/frontend/src/pages/project/GroupDetailsByIDPage/components/GroupDetailsSection.tsx index b23cfdad1..90c327067 100644 --- a/frontend/src/pages/project/GroupDetailsByIDPage/components/GroupDetailsSection.tsx +++ b/frontend/src/pages/project/GroupDetailsByIDPage/components/GroupDetailsSection.tsx @@ -15,6 +15,7 @@ import { } from "@app/components/v2"; import { CopyButton } from "@app/components/v2/CopyButton"; import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context"; +import { getProjectBaseURL } from "@app/helpers/project"; import { usePopUp } from "@app/hooks"; import { useDeleteGroupFromWorkspace } from "@app/hooks/api"; import { TGroupMembership } from "@app/hooks/api/groups/types"; @@ -46,7 +47,7 @@ export const GroupDetailsSection = ({ groupMembership }: Props) => { }); navigate({ - to: "/projects/$projectId/access-management", + to: `${getProjectBaseURL(currentWorkspace.type)}/access-management`, params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/project/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembersTable.tsx b/frontend/src/pages/project/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembersTable.tsx index 681deea42..bcffb428f 100644 --- a/frontend/src/pages/project/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembersTable.tsx +++ b/frontend/src/pages/project/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembersTable.tsx @@ -24,7 +24,7 @@ import { Tr } from "@app/components/v2"; import { useWorkspace } from "@app/context"; -import { getCurrentProductFromUrl, getProjectHomePage } from "@app/helpers/project"; +import { getProjectHomePage } from "@app/helpers/project"; import { getUserTablePreference, PreferenceKey, @@ -36,7 +36,6 @@ import { ActorType } from "@app/hooks/api/auditLogs/enums"; import { OrderByDirection } from "@app/hooks/api/generic/types"; import { useListProjectGroupUsers } from "@app/hooks/api/groups/queries"; import { EFilterReturnedUsers, TGroupMembership } from "@app/hooks/api/groups/types"; -import { ProjectType } from "@app/hooks/api/workspace/types"; import { GroupMembershipRow } from "./GroupMembershipRow"; @@ -137,9 +136,7 @@ export const GroupMembersTable = ({ groupMembership }: Props) => { text: "User privilege assumption has started" }); - const url = getProjectHomePage( - getCurrentProductFromUrl(window.location.href) || ProjectType.SecretManager - ); + const url = getProjectHomePage(currentWorkspace.type); window.location.href = url.replace("$projectId", currentWorkspace.id); } } diff --git a/frontend/src/pages/project/GroupDetailsByIDPage/route-cert-manager.tsx b/frontend/src/pages/project/GroupDetailsByIDPage/route-cert-manager.tsx new file mode 100644 index 000000000..cbf6e0072 --- /dev/null +++ b/frontend/src/pages/project/GroupDetailsByIDPage/route-cert-manager.tsx @@ -0,0 +1,33 @@ +import { createFileRoute, linkOptions } from "@tanstack/react-router"; + +import { ProjectAccessControlTabs } from "@app/types/project"; + +import { GroupDetailsByIDPage } from "./GroupDetailsByIDPage"; + +export const Route = createFileRoute( + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/groups/$groupId" +)({ + component: GroupDetailsByIDPage, + beforeLoad: ({ context, params }) => { + return { + breadcrumbs: [ + ...context.breadcrumbs, + { + label: "Access Control", + link: linkOptions({ + to: "/projects/cert-management/$projectId/access-management", + params: { + projectId: params.projectId + }, + search: { + selectedTab: ProjectAccessControlTabs.Groups + } + }) + }, + { + label: "Group" + } + ] + }; + } +}); diff --git a/frontend/src/pages/project/GroupDetailsByIDPage/route.tsx b/frontend/src/pages/project/GroupDetailsByIDPage/route-kms.tsx similarity index 79% rename from frontend/src/pages/project/GroupDetailsByIDPage/route.tsx rename to frontend/src/pages/project/GroupDetailsByIDPage/route-kms.tsx index 684e9fd87..c0dd210c1 100644 --- a/frontend/src/pages/project/GroupDetailsByIDPage/route.tsx +++ b/frontend/src/pages/project/GroupDetailsByIDPage/route-kms.tsx @@ -5,7 +5,7 @@ import { ProjectAccessControlTabs } from "@app/types/project"; import { GroupDetailsByIDPage } from "./GroupDetailsByIDPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/groups/$groupId" + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/groups/$groupId" )({ component: GroupDetailsByIDPage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Access Control", link: linkOptions({ - to: "/projects/$projectId/access-management", + to: "/projects/kms/$projectId/access-management", params: { projectId: params.projectId }, diff --git a/frontend/src/pages/project/GroupDetailsByIDPage/route-secret-manager.tsx b/frontend/src/pages/project/GroupDetailsByIDPage/route-secret-manager.tsx new file mode 100644 index 000000000..01349a83b --- /dev/null +++ b/frontend/src/pages/project/GroupDetailsByIDPage/route-secret-manager.tsx @@ -0,0 +1,33 @@ +import { createFileRoute, linkOptions } from "@tanstack/react-router"; + +import { ProjectAccessControlTabs } from "@app/types/project"; + +import { GroupDetailsByIDPage } from "./GroupDetailsByIDPage"; + +export const Route = createFileRoute( + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/groups/$groupId" +)({ + component: GroupDetailsByIDPage, + beforeLoad: ({ context, params }) => { + return { + breadcrumbs: [ + ...context.breadcrumbs, + { + label: "Access Control", + link: linkOptions({ + to: "/projects/secret-management/$projectId/access-management", + params: { + projectId: params.projectId + }, + search: { + selectedTab: ProjectAccessControlTabs.Groups + } + }) + }, + { + label: "Group" + } + ] + }; + } +}); diff --git a/frontend/src/pages/project/GroupDetailsByIDPage/route-secret-scanning.tsx b/frontend/src/pages/project/GroupDetailsByIDPage/route-secret-scanning.tsx new file mode 100644 index 000000000..ed86d0b65 --- /dev/null +++ b/frontend/src/pages/project/GroupDetailsByIDPage/route-secret-scanning.tsx @@ -0,0 +1,33 @@ +import { createFileRoute, linkOptions } from "@tanstack/react-router"; + +import { ProjectAccessControlTabs } from "@app/types/project"; + +import { GroupDetailsByIDPage } from "./GroupDetailsByIDPage"; + +export const Route = createFileRoute( + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/groups/$groupId" +)({ + component: GroupDetailsByIDPage, + beforeLoad: ({ context, params }) => { + return { + breadcrumbs: [ + ...context.breadcrumbs, + { + label: "Access Control", + link: linkOptions({ + to: "/projects/secret-scanning/$projectId/access-management", + params: { + projectId: params.projectId + }, + search: { + selectedTab: ProjectAccessControlTabs.Groups + } + }) + }, + { + label: "Group" + } + ] + }; + } +}); diff --git a/frontend/src/pages/project/GroupDetailsByIDPage/route-ssh.tsx b/frontend/src/pages/project/GroupDetailsByIDPage/route-ssh.tsx new file mode 100644 index 000000000..17427d706 --- /dev/null +++ b/frontend/src/pages/project/GroupDetailsByIDPage/route-ssh.tsx @@ -0,0 +1,33 @@ +import { createFileRoute, linkOptions } from "@tanstack/react-router"; + +import { ProjectAccessControlTabs } from "@app/types/project"; + +import { GroupDetailsByIDPage } from "./GroupDetailsByIDPage"; + +export const Route = createFileRoute( + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/groups/$groupId" +)({ + component: GroupDetailsByIDPage, + beforeLoad: ({ context, params }) => { + return { + breadcrumbs: [ + ...context.breadcrumbs, + { + label: "Access Control", + link: linkOptions({ + to: "/projects/ssh/$projectId/access-management", + params: { + projectId: params.projectId + }, + search: { + selectedTab: ProjectAccessControlTabs.Groups + } + }) + }, + { + label: "Group" + } + ] + }; + } +}); diff --git a/frontend/src/pages/project/IdentityDetailsByIDPage/IdentityDetailsByIDPage.tsx b/frontend/src/pages/project/IdentityDetailsByIDPage/IdentityDetailsByIDPage.tsx index bc4ae078f..19d6c4acc 100644 --- a/frontend/src/pages/project/IdentityDetailsByIDPage/IdentityDetailsByIDPage.tsx +++ b/frontend/src/pages/project/IdentityDetailsByIDPage/IdentityDetailsByIDPage.tsx @@ -20,7 +20,7 @@ import { ProjectPermissionSub, useWorkspace } from "@app/context"; -import { getCurrentProductFromUrl, getProjectHomePage } from "@app/helpers/project"; +import { getProjectBaseURL, getProjectHomePage } from "@app/helpers/project"; import { usePopUp } from "@app/hooks"; import { useAssumeProjectPrivileges, @@ -28,7 +28,6 @@ import { useGetWorkspaceIdentityMembershipDetails } from "@app/hooks/api"; import { ActorType } from "@app/hooks/api/auditLogs/enums"; -import { ProjectType } from "@app/hooks/api/workspace/types"; import { IdentityProjectAdditionalPrivilegeSection } from "./components/IdentityProjectAdditionalPrivilegeSection"; import { IdentityRoleDetailsSection } from "./components/IdentityRoleDetailsSection"; @@ -68,9 +67,7 @@ const Page = () => { type: "success", text: "Identity privilege assumption has started" }); - const url = getProjectHomePage( - getCurrentProductFromUrl(window.location.href) || ProjectType.SecretManager - ); + const url = getProjectHomePage(currentWorkspace.type); window.location.href = url.replace("$projectId", currentWorkspace.id); } } @@ -89,7 +86,7 @@ const Page = () => { }); handlePopUpClose("deleteIdentity"); navigate({ - to: "/projects/$projectId/access-management", + to: `${getProjectBaseURL(currentWorkspace.type)}/access-management` as const, params: { projectId: workspaceId }, diff --git a/frontend/src/pages/project/IdentityDetailsByIDPage/components/IdentityProjectAdditionalPrivilegeSection/IdentityProjectAdditionalPrivilegeModifySection.tsx b/frontend/src/pages/project/IdentityDetailsByIDPage/components/IdentityProjectAdditionalPrivilegeSection/IdentityProjectAdditionalPrivilegeModifySection.tsx index 3ba76475f..fe574a32d 100644 --- a/frontend/src/pages/project/IdentityDetailsByIDPage/components/IdentityProjectAdditionalPrivilegeSection/IdentityProjectAdditionalPrivilegeModifySection.tsx +++ b/frontend/src/pages/project/IdentityDetailsByIDPage/components/IdentityProjectAdditionalPrivilegeSection/IdentityProjectAdditionalPrivilegeModifySection.tsx @@ -225,7 +225,7 @@ export const IdentityProjectAdditionalPrivilegeModifySection = ({ > Save - + diff --git a/frontend/src/pages/project/IdentityDetailsByIDPage/route-cert-manager.tsx b/frontend/src/pages/project/IdentityDetailsByIDPage/route-cert-manager.tsx new file mode 100644 index 000000000..d6ef9aa73 --- /dev/null +++ b/frontend/src/pages/project/IdentityDetailsByIDPage/route-cert-manager.tsx @@ -0,0 +1,33 @@ +import { createFileRoute, linkOptions } from "@tanstack/react-router"; + +import { ProjectAccessControlTabs } from "@app/types/project"; + +import { IdentityDetailsByIDPage } from "./IdentityDetailsByIDPage"; + +export const Route = createFileRoute( + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/identities/$identityId" +)({ + component: IdentityDetailsByIDPage, + beforeLoad: ({ context, params }) => { + return { + breadcrumbs: [ + ...context.breadcrumbs, + { + label: "Access Control", + link: linkOptions({ + to: "/projects/cert-management/$projectId/access-management", + params: { + projectId: params.projectId + }, + search: { + selectedTab: ProjectAccessControlTabs.Identities + } + }) + }, + { + label: "Machine Identity" + } + ] + }; + } +}); diff --git a/frontend/src/pages/project/IdentityDetailsByIDPage/route.tsx b/frontend/src/pages/project/IdentityDetailsByIDPage/route-kms.tsx similarity index 79% rename from frontend/src/pages/project/IdentityDetailsByIDPage/route.tsx rename to frontend/src/pages/project/IdentityDetailsByIDPage/route-kms.tsx index 26bd99210..f4fb109e3 100644 --- a/frontend/src/pages/project/IdentityDetailsByIDPage/route.tsx +++ b/frontend/src/pages/project/IdentityDetailsByIDPage/route-kms.tsx @@ -5,7 +5,7 @@ import { ProjectAccessControlTabs } from "@app/types/project"; import { IdentityDetailsByIDPage } from "./IdentityDetailsByIDPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/identities/$identityId" + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/identities/$identityId" )({ component: IdentityDetailsByIDPage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Access Control", link: linkOptions({ - to: "/projects/$projectId/access-management", + to: "/projects/kms/$projectId/access-management", params: { projectId: params.projectId }, diff --git a/frontend/src/pages/project/IdentityDetailsByIDPage/route-secret-manager.tsx b/frontend/src/pages/project/IdentityDetailsByIDPage/route-secret-manager.tsx new file mode 100644 index 000000000..355428940 --- /dev/null +++ b/frontend/src/pages/project/IdentityDetailsByIDPage/route-secret-manager.tsx @@ -0,0 +1,33 @@ +import { createFileRoute, linkOptions } from "@tanstack/react-router"; + +import { ProjectAccessControlTabs } from "@app/types/project"; + +import { IdentityDetailsByIDPage } from "./IdentityDetailsByIDPage"; + +export const Route = createFileRoute( + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/identities/$identityId" +)({ + component: IdentityDetailsByIDPage, + beforeLoad: ({ context, params }) => { + return { + breadcrumbs: [ + ...context.breadcrumbs, + { + label: "Access Control", + link: linkOptions({ + to: "/projects/secret-management/$projectId/access-management", + params: { + projectId: params.projectId + }, + search: { + selectedTab: ProjectAccessControlTabs.Identities + } + }) + }, + { + label: "Machine Identity" + } + ] + }; + } +}); diff --git a/frontend/src/pages/project/IdentityDetailsByIDPage/route-secret-scanning.tsx b/frontend/src/pages/project/IdentityDetailsByIDPage/route-secret-scanning.tsx new file mode 100644 index 000000000..c5491bf72 --- /dev/null +++ b/frontend/src/pages/project/IdentityDetailsByIDPage/route-secret-scanning.tsx @@ -0,0 +1,33 @@ +import { createFileRoute, linkOptions } from "@tanstack/react-router"; + +import { ProjectAccessControlTabs } from "@app/types/project"; + +import { IdentityDetailsByIDPage } from "./IdentityDetailsByIDPage"; + +export const Route = createFileRoute( + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/identities/$identityId" +)({ + component: IdentityDetailsByIDPage, + beforeLoad: ({ context, params }) => { + return { + breadcrumbs: [ + ...context.breadcrumbs, + { + label: "Access Control", + link: linkOptions({ + to: "/projects/secret-scanning/$projectId/access-management", + params: { + projectId: params.projectId + }, + search: { + selectedTab: ProjectAccessControlTabs.Identities + } + }) + }, + { + label: "Machine Identity" + } + ] + }; + } +}); diff --git a/frontend/src/pages/project/IdentityDetailsByIDPage/route-ssh.tsx b/frontend/src/pages/project/IdentityDetailsByIDPage/route-ssh.tsx new file mode 100644 index 000000000..2a82c371f --- /dev/null +++ b/frontend/src/pages/project/IdentityDetailsByIDPage/route-ssh.tsx @@ -0,0 +1,33 @@ +import { createFileRoute, linkOptions } from "@tanstack/react-router"; + +import { ProjectAccessControlTabs } from "@app/types/project"; + +import { IdentityDetailsByIDPage } from "./IdentityDetailsByIDPage"; + +export const Route = createFileRoute( + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/identities/$identityId" +)({ + component: IdentityDetailsByIDPage, + beforeLoad: ({ context, params }) => { + return { + breadcrumbs: [ + ...context.breadcrumbs, + { + label: "Access Control", + link: linkOptions({ + to: "/projects/ssh/$projectId/access-management", + params: { + projectId: params.projectId + }, + search: { + selectedTab: ProjectAccessControlTabs.Identities + } + }) + }, + { + label: "Machine Identity" + } + ] + }; + } +}); diff --git a/frontend/src/pages/project/MemberDetailsByIDPage/MemberDetailsByIDPage.tsx b/frontend/src/pages/project/MemberDetailsByIDPage/MemberDetailsByIDPage.tsx index f84e0ea36..7bac32f75 100644 --- a/frontend/src/pages/project/MemberDetailsByIDPage/MemberDetailsByIDPage.tsx +++ b/frontend/src/pages/project/MemberDetailsByIDPage/MemberDetailsByIDPage.tsx @@ -21,7 +21,7 @@ import { useOrganization, useWorkspace } from "@app/context"; -import { getCurrentProductFromUrl, getProjectHomePage } from "@app/helpers/project"; +import { getProjectBaseURL, getProjectHomePage } from "@app/helpers/project"; import { usePopUp } from "@app/hooks"; import { useAssumeProjectPrivileges, @@ -29,7 +29,6 @@ import { useGetWorkspaceUserDetails } from "@app/hooks/api"; import { ActorType } from "@app/hooks/api/auditLogs/enums"; -import { ProjectType } from "@app/hooks/api/workspace/types"; import { MemberProjectAdditionalPrivilegeSection } from "./components/MemberProjectAdditionalPrivilegeSection"; import { MemberRoleDetailsSection } from "./components/MemberRoleDetailsSection"; @@ -73,9 +72,7 @@ export const Page = () => { text: "User privilege assumption has started" }); - const url = getProjectHomePage( - getCurrentProductFromUrl(window.location.href) || ProjectType.SecretManager - ); + const url = getProjectHomePage(currentWorkspace.type); window.location.href = url.replace("$projectId", currentWorkspace.id); } } @@ -96,7 +93,7 @@ export const Page = () => { type: "success" }); navigate({ - to: "/projects/$projectId/access-management", + to: `${getProjectBaseURL(currentWorkspace.type)}/access-management` as const, params: { projectId: currentWorkspace.id } diff --git a/frontend/src/pages/project/MemberDetailsByIDPage/components/MemberProjectAdditionalPrivilegeSection/MembershipProjectAdditionalPrivilegeModifySection.tsx b/frontend/src/pages/project/MemberDetailsByIDPage/components/MemberProjectAdditionalPrivilegeSection/MembershipProjectAdditionalPrivilegeModifySection.tsx index 92bdfc043..9817aefdb 100644 --- a/frontend/src/pages/project/MemberDetailsByIDPage/components/MemberProjectAdditionalPrivilegeSection/MembershipProjectAdditionalPrivilegeModifySection.tsx +++ b/frontend/src/pages/project/MemberDetailsByIDPage/components/MemberProjectAdditionalPrivilegeSection/MembershipProjectAdditionalPrivilegeModifySection.tsx @@ -221,7 +221,7 @@ export const MembershipProjectAdditionalPrivilegeModifySection = ({ > Save - + diff --git a/frontend/src/pages/project/MemberDetailsByIDPage/route-cert-manager.tsx b/frontend/src/pages/project/MemberDetailsByIDPage/route-cert-manager.tsx new file mode 100644 index 000000000..4946c2fe6 --- /dev/null +++ b/frontend/src/pages/project/MemberDetailsByIDPage/route-cert-manager.tsx @@ -0,0 +1,33 @@ +import { createFileRoute, linkOptions } from "@tanstack/react-router"; + +import { ProjectAccessControlTabs } from "@app/types/project"; + +import { MemberDetailsByIDPage } from "./MemberDetailsByIDPage"; + +export const Route = createFileRoute( + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/members/$membershipId" +)({ + component: MemberDetailsByIDPage, + beforeLoad: ({ context, params }) => { + return { + breadcrumbs: [ + ...context.breadcrumbs, + { + label: "Access Control", + link: linkOptions({ + to: "/projects/cert-management/$projectId/access-management", + params: { + projectId: params.projectId + }, + search: { + selectedTab: ProjectAccessControlTabs.Member + } + }) + }, + { + label: "User" + } + ] + }; + } +}); diff --git a/frontend/src/pages/project/MemberDetailsByIDPage/route.tsx b/frontend/src/pages/project/MemberDetailsByIDPage/route-kms.tsx similarity index 79% rename from frontend/src/pages/project/MemberDetailsByIDPage/route.tsx rename to frontend/src/pages/project/MemberDetailsByIDPage/route-kms.tsx index 2436c762f..6628de005 100644 --- a/frontend/src/pages/project/MemberDetailsByIDPage/route.tsx +++ b/frontend/src/pages/project/MemberDetailsByIDPage/route-kms.tsx @@ -5,7 +5,7 @@ import { ProjectAccessControlTabs } from "@app/types/project"; import { MemberDetailsByIDPage } from "./MemberDetailsByIDPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/members/$membershipId" + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/members/$membershipId" )({ component: MemberDetailsByIDPage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Access Control", link: linkOptions({ - to: "/projects/$projectId/access-management", + to: "/projects/kms/$projectId/access-management", params: { projectId: params.projectId }, diff --git a/frontend/src/pages/project/MemberDetailsByIDPage/route-secret-manager.tsx b/frontend/src/pages/project/MemberDetailsByIDPage/route-secret-manager.tsx new file mode 100644 index 000000000..2114e5b40 --- /dev/null +++ b/frontend/src/pages/project/MemberDetailsByIDPage/route-secret-manager.tsx @@ -0,0 +1,33 @@ +import { createFileRoute, linkOptions } from "@tanstack/react-router"; + +import { ProjectAccessControlTabs } from "@app/types/project"; + +import { MemberDetailsByIDPage } from "./MemberDetailsByIDPage"; + +export const Route = createFileRoute( + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/members/$membershipId" +)({ + component: MemberDetailsByIDPage, + beforeLoad: ({ context, params }) => { + return { + breadcrumbs: [ + ...context.breadcrumbs, + { + label: "Access Control", + link: linkOptions({ + to: "/projects/secret-management/$projectId/access-management", + params: { + projectId: params.projectId + }, + search: { + selectedTab: ProjectAccessControlTabs.Member + } + }) + }, + { + label: "User" + } + ] + }; + } +}); diff --git a/frontend/src/pages/project/MemberDetailsByIDPage/route-secret-scanning.tsx b/frontend/src/pages/project/MemberDetailsByIDPage/route-secret-scanning.tsx new file mode 100644 index 000000000..ff66305fd --- /dev/null +++ b/frontend/src/pages/project/MemberDetailsByIDPage/route-secret-scanning.tsx @@ -0,0 +1,33 @@ +import { createFileRoute, linkOptions } from "@tanstack/react-router"; + +import { ProjectAccessControlTabs } from "@app/types/project"; + +import { MemberDetailsByIDPage } from "./MemberDetailsByIDPage"; + +export const Route = createFileRoute( + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/members/$membershipId" +)({ + component: MemberDetailsByIDPage, + beforeLoad: ({ context, params }) => { + return { + breadcrumbs: [ + ...context.breadcrumbs, + { + label: "Access Control", + link: linkOptions({ + to: "/projects/secret-scanning/$projectId/access-management", + params: { + projectId: params.projectId + }, + search: { + selectedTab: ProjectAccessControlTabs.Member + } + }) + }, + { + label: "User" + } + ] + }; + } +}); diff --git a/frontend/src/pages/project/MemberDetailsByIDPage/route-ssh.tsx b/frontend/src/pages/project/MemberDetailsByIDPage/route-ssh.tsx new file mode 100644 index 000000000..577c84e3f --- /dev/null +++ b/frontend/src/pages/project/MemberDetailsByIDPage/route-ssh.tsx @@ -0,0 +1,33 @@ +import { createFileRoute, linkOptions } from "@tanstack/react-router"; + +import { ProjectAccessControlTabs } from "@app/types/project"; + +import { MemberDetailsByIDPage } from "./MemberDetailsByIDPage"; + +export const Route = createFileRoute( + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/members/$membershipId" +)({ + component: MemberDetailsByIDPage, + beforeLoad: ({ context, params }) => { + return { + breadcrumbs: [ + ...context.breadcrumbs, + { + label: "Access Control", + link: linkOptions({ + to: "/projects/ssh/$projectId/access-management", + params: { + projectId: params.projectId + }, + search: { + selectedTab: ProjectAccessControlTabs.Member + } + }) + }, + { + label: "User" + } + ] + }; + } +}); diff --git a/frontend/src/pages/project/RoleDetailsBySlugPage/RoleDetailsBySlugPage.tsx b/frontend/src/pages/project/RoleDetailsBySlugPage/RoleDetailsBySlugPage.tsx index af062aa13..95070c2c4 100644 --- a/frontend/src/pages/project/RoleDetailsBySlugPage/RoleDetailsBySlugPage.tsx +++ b/frontend/src/pages/project/RoleDetailsBySlugPage/RoleDetailsBySlugPage.tsx @@ -17,6 +17,7 @@ import { PageHeader } from "@app/components/v2"; import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context"; +import { getProjectBaseURL } from "@app/helpers/project"; import { useDeleteProjectRole, useGetProjectRoleBySlug } from "@app/hooks/api"; import { ProjectMembershipRole } from "@app/hooks/api/roles/types"; import { usePopUp } from "@app/hooks/usePopUp"; @@ -60,7 +61,7 @@ const Page = () => { }); handlePopUpClose("deleteRole"); navigate({ - to: "/projects/$projectId/access-management", + to: `${getProjectBaseURL(currentWorkspace.type)}/access-management` as const, params: { projectId }, diff --git a/frontend/src/pages/project/RoleDetailsBySlugPage/components/AddPoliciesButton.tsx b/frontend/src/pages/project/RoleDetailsBySlugPage/components/AddPoliciesButton.tsx index cedf07d05..abdf5c5d5 100644 --- a/frontend/src/pages/project/RoleDetailsBySlugPage/components/AddPoliciesButton.tsx +++ b/frontend/src/pages/project/RoleDetailsBySlugPage/components/AddPoliciesButton.tsx @@ -9,14 +9,16 @@ import { IconButton } from "@app/components/v2"; import { usePopUp } from "@app/hooks"; +import { ProjectType } from "@app/hooks/api/workspace/types"; import { PolicySelectionModal } from "@app/pages/project/RoleDetailsBySlugPage/components/PolicySelectionModal"; import { PolicyTemplateModal } from "@app/pages/project/RoleDetailsBySlugPage/components/PolicyTemplateModal"; type Props = { isDisabled?: boolean; + projectType: ProjectType; }; -export const AddPoliciesButton = ({ isDisabled }: Props) => { +export const AddPoliciesButton = ({ isDisabled, projectType }: Props) => { const { popUp, handlePopUpToggle, handlePopUpOpen, handlePopUpClose } = usePopUp([ "addPolicy", "addPolicyOptions", @@ -66,10 +68,12 @@ export const AddPoliciesButton = ({ isDisabled }: Props) => { handlePopUpToggle("addPolicy", isOpen)} /> handlePopUpToggle("applyTemplate", isOpen)} /> diff --git a/frontend/src/pages/project/RoleDetailsBySlugPage/components/DuplicateProjectRoleModal.tsx b/frontend/src/pages/project/RoleDetailsBySlugPage/components/DuplicateProjectRoleModal.tsx index ccc3e4ea5..24974225e 100644 --- a/frontend/src/pages/project/RoleDetailsBySlugPage/components/DuplicateProjectRoleModal.tsx +++ b/frontend/src/pages/project/RoleDetailsBySlugPage/components/DuplicateProjectRoleModal.tsx @@ -7,6 +7,7 @@ import { createNotification } from "@app/components/notifications"; import { Button, FormControl, Input, Modal, ModalContent, Spinner } from "@app/components/v2"; import { ProjectPermissionSub, useWorkspace } from "@app/context"; import { ProjectPermissionSecretActions } from "@app/context/ProjectPermissionContext/types"; +import { getProjectBaseURL } from "@app/helpers/project"; import { useCreateProjectRole, useGetProjectRoleBySlug } from "@app/hooks/api"; import { TProjectRole } from "@app/hooks/api/roles/types"; import { slugSchema } from "@app/lib/schemas"; @@ -80,7 +81,7 @@ const Content = ({ role, onClose }: ContentProps) => { }); navigate({ - to: "/projects/$projectId/roles/$roleSlug", + to: `${getProjectBaseURL(currentWorkspace.type)}/roles/$roleSlug` as const, params: { roleSlug: newRole.slug, projectId: currentWorkspace.id diff --git a/frontend/src/pages/project/RoleDetailsBySlugPage/components/PolicySelectionModal.tsx b/frontend/src/pages/project/RoleDetailsBySlugPage/components/PolicySelectionModal.tsx index a20bdf9b2..845c5f54e 100644 --- a/frontend/src/pages/project/RoleDetailsBySlugPage/components/PolicySelectionModal.tsx +++ b/frontend/src/pages/project/RoleDetailsBySlugPage/components/PolicySelectionModal.tsx @@ -19,26 +19,31 @@ import { Tr } from "@app/components/v2"; import { ProjectPermissionSub } from "@app/context"; +import { ProjectType } from "@app/hooks/api/workspace/types"; import { EXCLUDED_PERMISSION_SUBS, isConditionalSubjects, PROJECT_PERMISSION_OBJECT, + ProjectTypePermissionSubjects, TFormSchema } from "./ProjectRoleModifySection.utils"; type Props = { isOpen: boolean; onOpenChange: (isOpen: boolean) => void; + type: ProjectType; }; type ContentProps = { onClose: () => void; + + type: ProjectType; }; type TForm = { permissions: Record }; -const Content = ({ onClose }: ContentProps) => { +const Content = ({ onClose, type: projectType }: ContentProps) => { const rootForm = useFormContext(); const [search, setSearch] = useState(""); const { @@ -56,7 +61,12 @@ const Content = ({ onClose }: ContentProps) => { }); const filteredPolicies = Object.entries(PROJECT_PERMISSION_OBJECT) - .filter(([, { title }]) => (search ? title.toLowerCase().includes(search.toLowerCase()) : true)) + .filter( + ([subject, { title }]) => + ProjectTypePermissionSubjects[projectType ?? ProjectType.SecretManager][ + subject as ProjectPermissionSub + ] && (search ? title.toLowerCase().includes(search.toLowerCase()) : true) + ) .filter(([subject]) => !EXCLUDED_PERMISSION_SUBS.includes(subject as ProjectPermissionSub)) .sort((a, b) => a[1].title.localeCompare(b[1].title)) .map(([subject]) => subject); @@ -191,7 +201,7 @@ const Content = ({ onClose }: ContentProps) => { ); }; -export const PolicySelectionModal = ({ isOpen, onOpenChange }: Props) => { +export const PolicySelectionModal = ({ isOpen, onOpenChange, type }: Props) => { return ( { subTitle="Select one or more policies to add to this role." className="max-w-3xl" > - onOpenChange(false)} /> + onOpenChange(false)} type={type} /> ); diff --git a/frontend/src/pages/project/RoleDetailsBySlugPage/components/PolicyTemplateModal.tsx b/frontend/src/pages/project/RoleDetailsBySlugPage/components/PolicyTemplateModal.tsx index 69c43d63a..d9cae6244 100644 --- a/frontend/src/pages/project/RoleDetailsBySlugPage/components/PolicyTemplateModal.tsx +++ b/frontend/src/pages/project/RoleDetailsBySlugPage/components/PolicyTemplateModal.tsx @@ -13,6 +13,7 @@ import { ModalContent } from "@app/components/v2"; import { ProjectPermissionSub } from "@app/context"; +import { ProjectType } from "@app/hooks/api/workspace/types"; import { PROJECT_PERMISSION_OBJECT, @@ -24,19 +25,23 @@ import { type Props = { isOpen: boolean; onOpenChange: (isOpen: boolean) => void; + type: ProjectType; }; type ContentProps = { onClose: () => void; + type: ProjectType; }; -const Content = ({ onClose }: ContentProps) => { +const Content = ({ onClose, type: projectType }: ContentProps) => { const rootForm = useFormContext(); const [selectedTemplate, setSelectedTemplate] = useState(); const [conflictingSubjects, setConflictingSubjects] = useState([]); const [showConflictingSubjects, setShowConflictingSubjects] = useState(false); + const templates = RoleTemplates[projectType ?? ProjectType.SecretManager]; + const onSubmit = (skipConflicting = false) => { if (!selectedTemplate) { createNotification({ type: "error", text: "Please select a template" }); @@ -121,12 +126,12 @@ const Content = ({ onClose }: ContentProps) => { type="single" value={selectedTemplate?.id} onValueChange={(value) => - setSelectedTemplate(RoleTemplates.find((template) => template.id === value)) + setSelectedTemplate(templates.find((template) => template.id === value)) } collapsible className="w-full border-collapse" > - {RoleTemplates.map(({ name, description, permissions, id }) => ( + {templates.map(({ name, description, permissions, id }) => ( { ); }; -export const PolicyTemplateModal = ({ isOpen, onOpenChange }: Props) => { +export const PolicyTemplateModal = ({ isOpen, onOpenChange, type }: Props) => { return ( { subTitle="Select a template with prepopulated policies to get started. You can always add more policies later." className="max-w-3xl" > - onOpenChange(false)} /> + onOpenChange(false)} type={type} /> ); diff --git a/frontend/src/pages/project/RoleDetailsBySlugPage/components/ProjectRoleModifySection.utils.tsx b/frontend/src/pages/project/RoleDetailsBySlugPage/components/ProjectRoleModifySection.utils.tsx index 4e051f1d1..471246d04 100644 --- a/frontend/src/pages/project/RoleDetailsBySlugPage/components/ProjectRoleModifySection.utils.tsx +++ b/frontend/src/pages/project/RoleDetailsBySlugPage/components/ProjectRoleModifySection.utils.tsx @@ -1645,41 +1645,378 @@ export type RoleTemplate = { permissions: { subject: ProjectPermissionSub; actions: string[] }[]; }; -export const RoleTemplates = [ - { - id: "project-manager", - name: "Project Management Policies", - description: "Grants access to manage project members and settings", - permissions: [ +const projectManagerTemplate = ( + additionalPermissions: RoleTemplate["permissions"] = [] +): RoleTemplate => ({ + id: "project-manager", + name: "Project Management Policies", + description: "Grants access to manage project members and settings", + permissions: [ + { + subject: ProjectPermissionSub.AuditLogs, + actions: Object.values(ProjectPermissionActions) + }, + { + subject: ProjectPermissionSub.Groups, + actions: Object.values(ProjectPermissionGroupActions) + }, + { + subject: ProjectPermissionSub.Member, + actions: Object.values(ProjectPermissionMemberActions) + }, + { + subject: ProjectPermissionSub.Identity, + actions: Object.values(ProjectPermissionIdentityActions) + }, + { + subject: ProjectPermissionSub.Project, + actions: [ProjectPermissionActions.Edit, ProjectPermissionActions.Delete] + }, + { subject: ProjectPermissionSub.Role, actions: Object.values(ProjectPermissionActions) }, + { + subject: ProjectPermissionSub.Settings, + actions: [ProjectPermissionActions.Read, ProjectPermissionActions.Edit] + }, + ...additionalPermissions + ] +}); + +export const RoleTemplates: Record = { + [ProjectType.SSH]: [ + { + id: "ssh-viewer", + name: "SSH Viewing Policies", + description: "Grants read access to SSH certificates and hosts", + permissions: [ + { + subject: ProjectPermissionSub.SshCertificateAuthorities, + actions: [ProjectPermissionActions.Read] + }, + { + subject: ProjectPermissionSub.SshCertificates, + actions: [ProjectPermissionActions.Read] + }, + { + subject: ProjectPermissionSub.SshCertificateTemplates, + actions: [ProjectPermissionActions.Read] + }, + { + subject: ProjectPermissionSub.SshHosts, + actions: [ProjectPermissionSshHostActions.Read] + }, + { + subject: ProjectPermissionSub.SshHostGroups, + actions: [ProjectPermissionActions.Read] + } + ] + }, + { + id: "ssh-cert-editor", + name: "SSH Certificate Editing Policies", + description: "Grants read and edit access to SSH certificates", + permissions: [ + { + subject: ProjectPermissionSub.SshCertificateAuthorities, + actions: Object.values(ProjectPermissionActions) + }, + { + subject: ProjectPermissionSub.SshCertificates, + actions: Object.values(ProjectPermissionActions) + }, + { + subject: ProjectPermissionSub.SshCertificateTemplates, + actions: Object.values(ProjectPermissionActions) + } + ] + }, + { + id: "ssh-host-editor", + name: "SSH Host Editing Policies", + description: "Grants read and edit access to SSH hosts", + permissions: [ + { + subject: ProjectPermissionSub.SshHosts, + actions: Object.values(ProjectPermissionSshHostActions) + }, + { + subject: ProjectPermissionSub.SshHostGroups, + actions: Object.values(ProjectPermissionActions) + } + ] + }, + projectManagerTemplate() + ], + [ProjectType.KMS]: [ + { + id: "kms-viewer", + name: "KMS Viewing Policies", + description: "Grants read access to KMS keys and KMIP clients", + permissions: [ + { + subject: ProjectPermissionSub.Cmek, + actions: [ProjectPermissionCmekActions.Read] + }, + { + subject: ProjectPermissionSub.Kmip, + actions: [ProjectPermissionKmipActions.ReadClients] + } + ] + }, + { + id: "key-editor", + name: "KMS Key Editing Policies", + description: "Grants read and edit access to KMS keys", + permissions: [ + { + subject: ProjectPermissionSub.Cmek, + actions: Object.values(ProjectPermissionCmekActions) + } + ] + }, + { + id: "kmip-editor", + name: "KMIP Client Editing Policies", + description: "Grants read and edit access to KMIP clients", + permissions: [ + { + subject: ProjectPermissionSub.Kmip, + actions: Object.values(ProjectPermissionKmipActions) + } + ] + }, + projectManagerTemplate() + ], + [ProjectType.CertificateManager]: [ + { + id: "cert-viewer", + name: "Certificate Viewing Policies", + description: "Grants read access to certificates and related resources", + permissions: [ + { + subject: ProjectPermissionSub.PkiCollections, + actions: [ProjectPermissionActions.Read] + }, + { + subject: ProjectPermissionSub.PkiAlerts, + actions: [ProjectPermissionActions.Read] + }, + { + subject: ProjectPermissionSub.CertificateAuthorities, + actions: [ProjectPermissionActions.Read] + }, + { + subject: ProjectPermissionSub.CertificateTemplates, + actions: [ProjectPermissionActions.Read] + }, + { + subject: ProjectPermissionSub.Certificates, + actions: [ + ProjectPermissionCertificateActions.Read, + ProjectPermissionCertificateActions.ReadPrivateKey + ] + } + ] + }, + { + id: "cert-editor", + name: "Certificate Editing Policies", + description: "Grants read and edit access to certificates and related resources", + permissions: [ + { + subject: ProjectPermissionSub.PkiCollections, + actions: Object.values(ProjectPermissionActions) + }, + { + subject: ProjectPermissionSub.PkiAlerts, + actions: Object.values(ProjectPermissionActions) + }, + { + subject: ProjectPermissionSub.CertificateAuthorities, + actions: Object.values(ProjectPermissionActions) + }, + { + subject: ProjectPermissionSub.CertificateTemplates, + actions: Object.values(ProjectPermissionActions) + }, + { + subject: ProjectPermissionSub.Certificates, + actions: Object.values(ProjectPermissionCertificateActions) + } + ] + }, + projectManagerTemplate() + ], + [ProjectType.SecretScanning]: [ + { + id: "scanning-viewer", + name: "Secret Scanning Viewing Policies", + description: "Grants read access to data sources and findings", + permissions: [ + { + subject: ProjectPermissionSub.SecretScanningDataSources, + actions: [ + ProjectPermissionSecretScanningDataSourceActions.Read, + ProjectPermissionSecretScanningDataSourceActions.ReadResources, + ProjectPermissionSecretScanningDataSourceActions.ReadScans + ] + }, + { + subject: ProjectPermissionSub.SecretScanningFindings, + actions: [ProjectPermissionSecretScanningFindingActions.Read] + }, + { + subject: ProjectPermissionSub.SecretScanningConfigs, + actions: [ProjectPermissionSecretScanningConfigActions.Read] + } + ] + }, + { + id: "scanning-editor", + name: "Secret Scanning Editing Policies", + description: "Grants read and edit access to data sources and findings", + permissions: [ + { + subject: ProjectPermissionSub.SecretScanningDataSources, + actions: Object.values(ProjectPermissionSecretScanningDataSourceActions) + }, + { + subject: ProjectPermissionSub.SecretScanningFindings, + actions: Object.values(ProjectPermissionSecretScanningFindingActions) + }, + { + subject: ProjectPermissionSub.SecretScanningConfigs, + actions: [ProjectPermissionSecretScanningConfigActions.Read] + } + ] + }, + projectManagerTemplate([ { - subject: ProjectPermissionSub.AuditLogs, - actions: Object.values(ProjectPermissionActions) - }, - { - subject: ProjectPermissionSub.Groups, - actions: Object.values(ProjectPermissionGroupActions) - }, - { - subject: ProjectPermissionSub.Member, - actions: Object.values(ProjectPermissionMemberActions) - }, - { - subject: ProjectPermissionSub.Identity, - actions: Object.values(ProjectPermissionIdentityActions) - }, - { - subject: ProjectPermissionSub.Project, - actions: [ProjectPermissionActions.Edit, ProjectPermissionActions.Delete] - }, - { subject: ProjectPermissionSub.Role, actions: Object.values(ProjectPermissionActions) }, - { - subject: ProjectPermissionSub.Settings, - actions: [ProjectPermissionActions.Read, ProjectPermissionActions.Edit] - }, + subject: ProjectPermissionSub.SecretScanningConfigs, + actions: Object.values(ProjectPermissionSecretScanningConfigActions) + } + ]) + ], + [ProjectType.SecretManager]: [ + { + id: "secret-viewer", + name: "Secret Viewing Policies", + description: "Grants read access to secrets and related resources", + permissions: [ + { + subject: ProjectPermissionSub.SecretRollback, + actions: [ProjectPermissionActions.Read] + }, + { + subject: ProjectPermissionSub.SecretImports, + actions: [ProjectPermissionActions.Read] + }, + { + subject: ProjectPermissionSub.Secrets, + actions: [ + ProjectPermissionSecretActions.DescribeSecret, + ProjectPermissionSecretActions.ReadValue + ] + }, + { + subject: ProjectPermissionSub.DynamicSecrets, + actions: [ProjectPermissionDynamicSecretActions.ReadRootCredential] + }, + { + subject: ProjectPermissionSub.Environments, + actions: [ProjectPermissionActions.Read] + }, + { + subject: ProjectPermissionSub.Tags, + actions: [ProjectPermissionActions.Read] + }, + { + subject: ProjectPermissionSub.SecretRotation, + actions: [ProjectPermissionSecretRotationActions.Read] + }, + { + subject: ProjectPermissionSub.Integrations, + actions: [ProjectPermissionActions.Read] + }, + { + subject: ProjectPermissionSub.SecretSyncs, + actions: [ProjectPermissionSecretSyncActions.Read] + }, + { + subject: ProjectPermissionSub.Commits, + actions: [ProjectPermissionCommitsActions.Read] + } + ] + }, + { + id: "secret-editor", + name: "Secret Editing Policies", + description: "Grants read and edit access to secrets and related resources", + permissions: [ + { + subject: ProjectPermissionSub.Environments, + actions: Object.values(ProjectPermissionActions) + }, + { + subject: ProjectPermissionSub.DynamicSecrets, + actions: Object.values(ProjectPermissionDynamicSecretActions) + }, + { + subject: ProjectPermissionSub.Secrets, + actions: [ + ProjectPermissionSecretActions.DescribeSecret, + ProjectPermissionSecretActions.ReadValue, + ProjectPermissionSecretActions.Edit, + ProjectPermissionSecretActions.Create, + ProjectPermissionSecretActions.Delete + ] + }, + { + subject: ProjectPermissionSub.SecretRollback, + actions: [ProjectPermissionActions.Read, ProjectPermissionActions.Create] + }, + { + subject: ProjectPermissionSub.Tags, + actions: Object.values(ProjectPermissionActions) + }, + { + subject: ProjectPermissionSub.SecretImports, + actions: Object.values(ProjectPermissionActions) + }, + { + subject: ProjectPermissionSub.SecretRotation, + actions: Object.values(ProjectPermissionSecretRotationActions) + }, + { + subject: ProjectPermissionSub.SecretFolders, + actions: [ + ProjectPermissionActions.Create, + ProjectPermissionActions.Edit, + ProjectPermissionActions.Delete + ] + }, + { + subject: ProjectPermissionSub.Integrations, + actions: Object.values(ProjectPermissionActions) + }, + { + subject: ProjectPermissionSub.SecretSyncs, + actions: Object.values(ProjectPermissionSecretSyncActions) + }, + { + subject: ProjectPermissionSub.Commits, + actions: Object.values(ProjectPermissionCommitsActions) + } + ] + }, + projectManagerTemplate([ { subject: ProjectPermissionSub.IpAllowList, actions: Object.values(ProjectPermissionActions) }, + { + subject: ProjectPermissionSub.Kms, + actions: [ProjectPermissionActions.Edit] + }, { subject: ProjectPermissionSub.SecretApproval, actions: Object.values(ProjectPermissionActions) @@ -1692,314 +2029,6 @@ export const RoleTemplates = [ subject: ProjectPermissionSub.Webhooks, actions: Object.values(ProjectPermissionActions) } - ] - }, - { - id: "ssh-viewer", - name: "SSH Viewing Policies", - description: "Grants read access to SSH certificates and hosts", - permissions: [ - { - subject: ProjectPermissionSub.SshCertificateAuthorities, - actions: [ProjectPermissionActions.Read] - }, - { - subject: ProjectPermissionSub.SshCertificates, - actions: [ProjectPermissionActions.Read] - }, - { - subject: ProjectPermissionSub.SshCertificateTemplates, - actions: [ProjectPermissionActions.Read] - }, - { - subject: ProjectPermissionSub.SshHosts, - actions: [ProjectPermissionSshHostActions.Read] - }, - { - subject: ProjectPermissionSub.SshHostGroups, - actions: [ProjectPermissionActions.Read] - } - ] - }, - { - id: "ssh-cert-editor", - name: "SSH Certificate Editing Policies", - description: "Grants read and edit access to SSH certificates", - permissions: [ - { - subject: ProjectPermissionSub.SshCertificateAuthorities, - actions: Object.values(ProjectPermissionActions) - }, - { - subject: ProjectPermissionSub.SshCertificates, - actions: Object.values(ProjectPermissionActions) - }, - { - subject: ProjectPermissionSub.SshCertificateTemplates, - actions: Object.values(ProjectPermissionActions) - } - ] - }, - { - id: "ssh-host-editor", - name: "SSH Host Editing Policies", - description: "Grants read and edit access to SSH hosts", - permissions: [ - { - subject: ProjectPermissionSub.SshHosts, - actions: Object.values(ProjectPermissionSshHostActions) - }, - { - subject: ProjectPermissionSub.SshHostGroups, - actions: Object.values(ProjectPermissionActions) - } - ] - }, - { - id: "kms-viewer", - name: "KMS Viewing Policies", - description: "Grants read access to KMS keys and KMIP clients", - permissions: [ - { - subject: ProjectPermissionSub.Cmek, - actions: [ProjectPermissionCmekActions.Read] - }, - { - subject: ProjectPermissionSub.Kmip, - actions: [ProjectPermissionKmipActions.ReadClients] - } - ] - }, - { - id: "key-editor", - name: "KMS Key Editing Policies", - description: "Grants read and edit access to KMS keys", - permissions: [ - { - subject: ProjectPermissionSub.Cmek, - actions: Object.values(ProjectPermissionCmekActions) - } - ] - }, - { - id: "kmip-editor", - name: "KMIP Client Editing Policies", - description: "Grants read and edit access to KMIP clients", - permissions: [ - { - subject: ProjectPermissionSub.Kmip, - actions: Object.values(ProjectPermissionKmipActions) - } - ] - }, - { - id: "cert-viewer", - name: "Certificate Viewing Policies", - description: "Grants read access to certificates and related resources", - permissions: [ - { - subject: ProjectPermissionSub.PkiCollections, - actions: [ProjectPermissionActions.Read] - }, - { - subject: ProjectPermissionSub.PkiAlerts, - actions: [ProjectPermissionActions.Read] - }, - { - subject: ProjectPermissionSub.CertificateAuthorities, - actions: [ProjectPermissionActions.Read] - }, - { - subject: ProjectPermissionSub.CertificateTemplates, - actions: [ProjectPermissionActions.Read] - }, - { - subject: ProjectPermissionSub.Certificates, - actions: [ - ProjectPermissionCertificateActions.Read, - ProjectPermissionCertificateActions.ReadPrivateKey - ] - } - ] - }, - { - id: "cert-editor", - name: "Certificate Editing Policies", - description: "Grants read and edit access to certificates and related resources", - permissions: [ - { - subject: ProjectPermissionSub.PkiCollections, - actions: Object.values(ProjectPermissionActions) - }, - { - subject: ProjectPermissionSub.PkiAlerts, - actions: Object.values(ProjectPermissionActions) - }, - { - subject: ProjectPermissionSub.CertificateAuthorities, - actions: Object.values(ProjectPermissionActions) - }, - { - subject: ProjectPermissionSub.CertificateTemplates, - actions: Object.values(ProjectPermissionActions) - }, - { - subject: ProjectPermissionSub.Certificates, - actions: Object.values(ProjectPermissionCertificateActions) - } - ] - }, - { - id: "scanning-viewer", - name: "Secret Scanning Viewing Policies", - description: "Grants read access to data sources and findings", - permissions: [ - { - subject: ProjectPermissionSub.SecretScanningDataSources, - actions: [ - ProjectPermissionSecretScanningDataSourceActions.Read, - ProjectPermissionSecretScanningDataSourceActions.ReadResources, - ProjectPermissionSecretScanningDataSourceActions.ReadScans - ] - }, - { - subject: ProjectPermissionSub.SecretScanningFindings, - actions: [ProjectPermissionSecretScanningFindingActions.Read] - }, - { - subject: ProjectPermissionSub.SecretScanningConfigs, - actions: [ProjectPermissionSecretScanningConfigActions.Read] - } - ] - }, - { - id: "scanning-editor", - name: "Secret Scanning Editing Policies", - description: "Grants read and edit access to data sources and findings", - permissions: [ - { - subject: ProjectPermissionSub.SecretScanningDataSources, - actions: Object.values(ProjectPermissionSecretScanningDataSourceActions) - }, - { - subject: ProjectPermissionSub.SecretScanningFindings, - actions: Object.values(ProjectPermissionSecretScanningFindingActions) - }, - { - subject: ProjectPermissionSub.SecretScanningConfigs, - actions: [ProjectPermissionSecretScanningConfigActions.Read] - } - ] - }, - { - id: "secret-viewer", - name: "Secret Viewing Policies", - description: "Grants read access to secrets and related resources", - permissions: [ - { - subject: ProjectPermissionSub.SecretRollback, - actions: [ProjectPermissionActions.Read] - }, - { - subject: ProjectPermissionSub.SecretImports, - actions: [ProjectPermissionActions.Read] - }, - { - subject: ProjectPermissionSub.Secrets, - actions: [ - ProjectPermissionSecretActions.DescribeSecret, - ProjectPermissionSecretActions.ReadValue - ] - }, - { - subject: ProjectPermissionSub.DynamicSecrets, - actions: [ProjectPermissionDynamicSecretActions.ReadRootCredential] - }, - { - subject: ProjectPermissionSub.Environments, - actions: [ProjectPermissionActions.Read] - }, - { - subject: ProjectPermissionSub.Tags, - actions: [ProjectPermissionActions.Read] - }, - { - subject: ProjectPermissionSub.SecretRotation, - actions: [ProjectPermissionSecretRotationActions.Read] - }, - { - subject: ProjectPermissionSub.Integrations, - actions: [ProjectPermissionActions.Read] - }, - { - subject: ProjectPermissionSub.SecretSyncs, - actions: [ProjectPermissionSecretSyncActions.Read] - }, - { - subject: ProjectPermissionSub.Commits, - actions: [ProjectPermissionCommitsActions.Read] - } - ] - }, - { - id: "secret-editor", - name: "Secret Editing Policies", - description: "Grants read and edit access to secrets and related resources", - permissions: [ - { - subject: ProjectPermissionSub.Environments, - actions: Object.values(ProjectPermissionActions) - }, - { - subject: ProjectPermissionSub.DynamicSecrets, - actions: Object.values(ProjectPermissionDynamicSecretActions) - }, - { - subject: ProjectPermissionSub.Secrets, - actions: [ - ProjectPermissionSecretActions.DescribeSecret, - ProjectPermissionSecretActions.ReadValue, - ProjectPermissionSecretActions.Edit, - ProjectPermissionSecretActions.Create, - ProjectPermissionSecretActions.Delete - ] - }, - { - subject: ProjectPermissionSub.SecretRollback, - actions: [ProjectPermissionActions.Read, ProjectPermissionActions.Create] - }, - { - subject: ProjectPermissionSub.Tags, - actions: Object.values(ProjectPermissionActions) - }, - { - subject: ProjectPermissionSub.SecretImports, - actions: Object.values(ProjectPermissionActions) - }, - { - subject: ProjectPermissionSub.SecretRotation, - actions: Object.values(ProjectPermissionSecretRotationActions) - }, - { - subject: ProjectPermissionSub.SecretFolders, - actions: [ - ProjectPermissionActions.Create, - ProjectPermissionActions.Edit, - ProjectPermissionActions.Delete - ] - }, - { - subject: ProjectPermissionSub.Integrations, - actions: Object.values(ProjectPermissionActions) - }, - { - subject: ProjectPermissionSub.SecretSyncs, - actions: Object.values(ProjectPermissionSecretSyncActions) - }, - { - subject: ProjectPermissionSub.Commits, - actions: Object.values(ProjectPermissionCommitsActions) - } - ] - } -]; + ]) + ] +}; diff --git a/frontend/src/pages/project/RoleDetailsBySlugPage/components/RoleModal.tsx b/frontend/src/pages/project/RoleDetailsBySlugPage/components/RoleModal.tsx index 0f1433af3..eb7a2ba83 100644 --- a/frontend/src/pages/project/RoleDetailsBySlugPage/components/RoleModal.tsx +++ b/frontend/src/pages/project/RoleDetailsBySlugPage/components/RoleModal.tsx @@ -7,6 +7,7 @@ import { z } from "zod"; import { createNotification } from "@app/components/notifications"; import { Button, FormControl, Input, Modal, ModalContent } from "@app/components/v2"; import { useWorkspace } from "@app/context"; +import { getProjectBaseURL } from "@app/helpers/project"; import { useCreateProjectRole, useGetProjectRoleBySlug, @@ -100,7 +101,7 @@ export const RoleModal = ({ popUp, handlePopUpToggle }: Props) => { }); navigate({ - to: "/projects/$projectId/roles/$roleSlug", + to: `${getProjectBaseURL(currentWorkspace.type)}/roles/$roleSlug` as const, params: { roleSlug: newRole.slug, projectId diff --git a/frontend/src/pages/project/RoleDetailsBySlugPage/components/RolePermissionsSection.tsx b/frontend/src/pages/project/RoleDetailsBySlugPage/components/RolePermissionsSection.tsx index 216d514e4..dd43ad89c 100644 --- a/frontend/src/pages/project/RoleDetailsBySlugPage/components/RolePermissionsSection.tsx +++ b/frontend/src/pages/project/RoleDetailsBySlugPage/components/RolePermissionsSection.tsx @@ -14,6 +14,7 @@ import { ProjectPermissionSet } from "@app/context/ProjectPermissionContext"; import { evaluatePermissionsAbility } from "@app/helpers/permissions"; import { useGetProjectRoleBySlug, useUpdateProjectRole } from "@app/hooks/api"; import { ProjectMembershipRole } from "@app/hooks/api/roles/types"; +import { ProjectType } from "@app/hooks/api/workspace/types"; import { AddPoliciesButton } from "./AddPoliciesButton"; import { DynamicSecretPermissionConditions } from "./DynamicSecretPermissionConditions"; @@ -121,6 +122,8 @@ export const RolePermissionsSection = ({ roleSlug, isDisabled }: Props) => { (role?.slug ?? "") as ProjectMembershipRole ); + const isSecretManagerProject = currentWorkspace.type === ProjectType.SecretManager; + const permissions = form.watch("permissions"); const formattedPermissions = useMemo( @@ -171,7 +174,7 @@ export const RolePermissionsSection = ({ roleSlug, isDisabled }: Props) => { Save - + )} @@ -206,7 +209,7 @@ export const RolePermissionsSection = ({ roleSlug, isDisabled }: Props) => { - {showAccessTree && ( + {isSecretManagerProject && showAccessTree && ( { + return { + breadcrumbs: [ + ...context.breadcrumbs, + { + label: "Access Control", + link: linkOptions({ + to: "/projects/cert-management/$projectId/access-management", + params: { + projectId: params.projectId + }, + search: { + selectedTab: ProjectAccessControlTabs.Roles + } + }) + }, + { + label: "Roles" + } + ] + }; + } +}); diff --git a/frontend/src/pages/project/RoleDetailsBySlugPage/route.tsx b/frontend/src/pages/project/RoleDetailsBySlugPage/route-kms.tsx similarity index 79% rename from frontend/src/pages/project/RoleDetailsBySlugPage/route.tsx rename to frontend/src/pages/project/RoleDetailsBySlugPage/route-kms.tsx index c230df0a3..e1eae2756 100644 --- a/frontend/src/pages/project/RoleDetailsBySlugPage/route.tsx +++ b/frontend/src/pages/project/RoleDetailsBySlugPage/route-kms.tsx @@ -5,7 +5,7 @@ import { ProjectAccessControlTabs } from "@app/types/project"; import { RoleDetailsBySlugPage } from "./RoleDetailsBySlugPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/roles/$roleSlug" + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/roles/$roleSlug" )({ component: RoleDetailsBySlugPage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Access Control", link: linkOptions({ - to: "/projects/$projectId/access-management", + to: "/projects/kms/$projectId/access-management", params: { projectId: params.projectId }, diff --git a/frontend/src/pages/project/RoleDetailsBySlugPage/route-secret-manager.tsx b/frontend/src/pages/project/RoleDetailsBySlugPage/route-secret-manager.tsx new file mode 100644 index 000000000..ad4d44d67 --- /dev/null +++ b/frontend/src/pages/project/RoleDetailsBySlugPage/route-secret-manager.tsx @@ -0,0 +1,33 @@ +import { createFileRoute, linkOptions } from "@tanstack/react-router"; + +import { ProjectAccessControlTabs } from "@app/types/project"; + +import { RoleDetailsBySlugPage } from "./RoleDetailsBySlugPage"; + +export const Route = createFileRoute( + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/roles/$roleSlug" +)({ + component: RoleDetailsBySlugPage, + beforeLoad: ({ context, params }) => { + return { + breadcrumbs: [ + ...context.breadcrumbs, + { + label: "Access Control", + link: linkOptions({ + to: "/projects/secret-management/$projectId/access-management", + params: { + projectId: params.projectId + }, + search: { + selectedTab: ProjectAccessControlTabs.Roles + } + }) + }, + { + label: "Roles" + } + ] + }; + } +}); diff --git a/frontend/src/pages/project/RoleDetailsBySlugPage/route-secret-scanning.tsx b/frontend/src/pages/project/RoleDetailsBySlugPage/route-secret-scanning.tsx new file mode 100644 index 000000000..6d5ad64e5 --- /dev/null +++ b/frontend/src/pages/project/RoleDetailsBySlugPage/route-secret-scanning.tsx @@ -0,0 +1,33 @@ +import { createFileRoute, linkOptions } from "@tanstack/react-router"; + +import { ProjectAccessControlTabs } from "@app/types/project"; + +import { RoleDetailsBySlugPage } from "./RoleDetailsBySlugPage"; + +export const Route = createFileRoute( + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/roles/$roleSlug" +)({ + component: RoleDetailsBySlugPage, + beforeLoad: ({ context, params }) => { + return { + breadcrumbs: [ + ...context.breadcrumbs, + { + label: "Access Control", + link: linkOptions({ + to: "/projects/secret-scanning/$projectId/access-management", + params: { + projectId: params.projectId + }, + search: { + selectedTab: ProjectAccessControlTabs.Roles + } + }) + }, + { + label: "Roles" + } + ] + }; + } +}); diff --git a/frontend/src/pages/project/RoleDetailsBySlugPage/route-ssh.tsx b/frontend/src/pages/project/RoleDetailsBySlugPage/route-ssh.tsx new file mode 100644 index 000000000..1f06f795d --- /dev/null +++ b/frontend/src/pages/project/RoleDetailsBySlugPage/route-ssh.tsx @@ -0,0 +1,33 @@ +import { createFileRoute, linkOptions } from "@tanstack/react-router"; + +import { ProjectAccessControlTabs } from "@app/types/project"; + +import { RoleDetailsBySlugPage } from "./RoleDetailsBySlugPage"; + +export const Route = createFileRoute( + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/roles/$roleSlug" +)({ + component: RoleDetailsBySlugPage, + beforeLoad: ({ context, params }) => { + return { + breadcrumbs: [ + ...context.breadcrumbs, + { + label: "Access Control", + link: linkOptions({ + to: "/projects/ssh/$projectId/access-management", + params: { + projectId: params.projectId + }, + search: { + selectedTab: ProjectAccessControlTabs.Roles + } + }) + }, + { + label: "Roles" + } + ] + }; + } +}); diff --git a/frontend/src/pages/project/SettingsPage/SettingsPage.tsx b/frontend/src/pages/project/SettingsPage/SettingsPage.tsx deleted file mode 100644 index 76d88947a..000000000 --- a/frontend/src/pages/project/SettingsPage/SettingsPage.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { Helmet } from "react-helmet"; -import { useTranslation } from "react-i18next"; - -import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2"; - -import { ProjectGeneralTab } from "./components/ProjectGeneralTab"; - -const tabs = [{ name: "General", key: "tab-project-general", Component: ProjectGeneralTab }]; - -export const SettingsPage = () => { - const { t } = useTranslation(); - - return ( - - - {t("common.head-title", { title: t("settings.project.title") })} - - - - - - {tabs.map((tab) => ( - - {tab.name} - - ))} - - {tabs.map(({ key, Component }) => ( - - - - ))} - - - - ); -}; diff --git a/frontend/src/pages/project/SettingsPage/route.tsx b/frontend/src/pages/project/SettingsPage/route.tsx deleted file mode 100644 index 0718ea2f2..000000000 --- a/frontend/src/pages/project/SettingsPage/route.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { createFileRoute } from "@tanstack/react-router"; - -import { SettingsPage } from "./SettingsPage"; - -export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/settings" -)({ - component: SettingsPage, - beforeLoad: ({ context }) => { - return { - breadcrumbs: [ - ...context.breadcrumbs, - { - label: "Settings" - } - ] - }; - } -}); diff --git a/frontend/src/pages/project/layout-general.tsx b/frontend/src/pages/project/layout-general.tsx deleted file mode 100644 index ae2f764d0..000000000 --- a/frontend/src/pages/project/layout-general.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { createFileRoute } from "@tanstack/react-router"; - -import { ProjectGeneralLayout } from "@app/layouts/ProjectGeneralLayout"; - -export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout" -)({ - component: ProjectGeneralLayout -}); diff --git a/frontend/src/pages/project/layout.tsx b/frontend/src/pages/project/layout.tsx deleted file mode 100644 index 8f85cb1a5..000000000 --- a/frontend/src/pages/project/layout.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { createFileRoute } from "@tanstack/react-router"; - -import { BreadcrumbTypes } from "@app/components/v2"; -import { workspaceKeys } from "@app/hooks/api"; -import { fetchUserProjectPermissions, roleQueryKeys } from "@app/hooks/api/roles/queries"; -import { fetchWorkspaceById } from "@app/hooks/api/workspace/queries"; -import { ProjectLayout } from "@app/layouts/ProjectLayout"; -import { ProjectSelect } from "@app/layouts/ProjectLayout/components/ProjectSelect"; - -export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout" -)({ - component: ProjectLayout, - beforeLoad: async ({ params, context }) => { - const project = await context.queryClient.ensureQueryData({ - queryKey: workspaceKeys.getWorkspaceById(params.projectId), - queryFn: () => fetchWorkspaceById(params.projectId) - }); - - await context.queryClient.ensureQueryData({ - queryKey: roleQueryKeys.getUserProjectPermissions({ - workspaceId: params.projectId - }), - queryFn: () => fetchUserProjectPermissions({ workspaceId: params.projectId }) - }); - - return { - project, - breadcrumbs: [ - { - type: BreadcrumbTypes.Component, - component: ProjectSelect - } - ] - }; - } -}); diff --git a/frontend/src/pages/secret-manager/CommitDetailsPage/CommitDetailsPage.tsx b/frontend/src/pages/secret-manager/CommitDetailsPage/CommitDetailsPage.tsx index 05a3c7231..06f79e9f0 100644 --- a/frontend/src/pages/secret-manager/CommitDetailsPage/CommitDetailsPage.tsx +++ b/frontend/src/pages/secret-manager/CommitDetailsPage/CommitDetailsPage.tsx @@ -34,7 +34,7 @@ export const CommitDetailsPage = () => { const handleGoBackToHistory = () => { navigate({ - to: "/projects/$projectId/secret-manager/commits/$environment/$folderId", + to: "/projects/secret-management/$projectId/commits/$environment/$folderId", params: { projectId: currentWorkspace.id, folderId, @@ -49,7 +49,7 @@ export const CommitDetailsPage = () => { const handleGoToRollbackPreview = () => { navigate({ - to: "/projects/$projectId/secret-manager/commits/$environment/$folderId/$commitId/restore", + to: "/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId/restore", params: { projectId: currentWorkspace.id, folderId, diff --git a/frontend/src/pages/secret-manager/CommitDetailsPage/components/CommitDetailsTab/CommitDetailsTab.tsx b/frontend/src/pages/secret-manager/CommitDetailsPage/components/CommitDetailsTab/CommitDetailsTab.tsx index c403f9f3f..483d00861 100644 --- a/frontend/src/pages/secret-manager/CommitDetailsPage/components/CommitDetailsTab/CommitDetailsTab.tsx +++ b/frontend/src/pages/secret-manager/CommitDetailsPage/components/CommitDetailsTab/CommitDetailsTab.tsx @@ -1,5 +1,10 @@ import { useEffect, useState } from "react"; -import { faAngleDown } from "@fortawesome/free-solid-svg-icons"; +import { + faAngleDown, + faChevronLeft, + faCodeCommit, + faWarning +} from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { DropdownMenuItem } from "@radix-ui/react-dropdown-menu"; import { useSearch } from "@tanstack/react-router"; @@ -7,12 +12,14 @@ import { useSearch } from "@tanstack/react-router"; import { createNotification } from "@app/components/notifications"; import { ProjectPermissionCan } from "@app/components/permissions"; import { + Button, + ContentLoader, DeleteActionModal, DropdownMenu, DropdownMenuContent, DropdownMenuTrigger, - IconButton, - Spinner + EmptyState, + PageHeader } from "@app/components/v2"; import { ROUTE_PATHS } from "@app/const/routes"; import { @@ -108,25 +115,25 @@ export const CommitDetailsTab = ({ // If no commit is selected or data is loading, show appropriate message if (!selectedCommitId) { return ( - - Select a commit to view details - + + goBackToHistory()}> + Back to Commits + + ); } if (isLoading) { - return ( - - - - ); + return ; } if (!commitDetails) { return ( - - No details found for this commit - + + goBackToHistory()}> + Back to Commits + + ); } @@ -138,9 +145,11 @@ export const CommitDetailsTab = ({ } catch (error) { console.error("Failed to parse commit details:", error); return ( - - Error parsing commit details - + + goBackToHistory()}> + Back to Commits + + ); } @@ -223,13 +232,12 @@ export const CommitDetailsTab = ({ // Render an item from the merged list const renderMergedItem = (item: MergedItem): JSX.Element => { return ( - - toggleItemCollapsed(id)} - /> - + toggleItemCollapsed(id)} + /> ); }; @@ -240,114 +248,104 @@ export const CommitDetailsTab = ({ "Unknown"; return ( - - - - - - - - {parsedCommitDetails.changes?.message || "No message"} - - - - - - Commited by - {actorDisplay} - on - - {formatDisplayDate( - parsedCommitDetails.changes?.createdAt || new Date().toISOString() - )} - - {parsedCommitDetails.changes?.isLatest && ( - (Latest) - )} - - - - - - {(isAllowed) => ( - - + } + onClick={() => { + goBackToHistory(); + }} + > + Commit History + + + Commited by {actorDisplay} on{" "} + {formatDisplayDate(parsedCommitDetails.changes?.createdAt || new Date().toISOString())} + {parsedCommitDetails.changes?.isLatest && ( + (Latest) + )} + > + } + > + + {(isAllowed) => ( + + + } + variant="solid" + className="h-min" + colorSchema="secondary" + > + Restore Options + + + + {!parsedCommitDetails.changes.isLatest && ( + goToRollbackPreview()} > - - Restore Options - - - - - {!parsedCommitDetails.changes.isLatest && ( - goToRollbackPreview()} - > - - - - Roll back to this commit - - - Return this folder to its exact state at the time of this commit, - discarding all other changes made after it - - - - - )} - - handlePopUpOpen("revertChanges")} - > - - - Revert changes - - Will restore to the previous version of affected resources - - + + + + Roll back to this commit + + + Return this folder to its exact state at the time of this commit, + discarding all other changes made after it + - - - - )} - - + + + )} + handlePopUpOpen("revertChanges")} + > + + + Revert changes + + Will restore to the previous version of affected resources + + + + + + + )} + + + + + Commit Changes - - - - - {sortedChangedItems.length > 0 ? ( - sortedChangedItems.map((item) => renderMergedItem(item)) - ) : ( - - No changed items found - - )} - + + + {sortedChangedItems.length > 0 ? ( + sortedChangedItems.map((item) => renderMergedItem(item)) + ) : ( + + )} - - + > ); }; diff --git a/frontend/src/pages/secret-manager/CommitDetailsPage/components/RollbackPreviewTab/RollbackPreviewTab.tsx b/frontend/src/pages/secret-manager/CommitDetailsPage/components/RollbackPreviewTab/RollbackPreviewTab.tsx index b14a5fe94..e06daea38 100644 --- a/frontend/src/pages/secret-manager/CommitDetailsPage/components/RollbackPreviewTab/RollbackPreviewTab.tsx +++ b/frontend/src/pages/secret-manager/CommitDetailsPage/components/RollbackPreviewTab/RollbackPreviewTab.tsx @@ -102,7 +102,7 @@ export const RollbackPreviewTab = (): JSX.Element => { const goBackToHistory = () => { navigate({ - to: "/projects/$projectId/secret-manager/commits/$environment/$folderId", + to: "/projects/secret-management/$projectId/commits/$environment/$folderId", params: { projectId: currentWorkspace.id, folderId, diff --git a/frontend/src/pages/secret-manager/CommitDetailsPage/components/RollbackPreviewTab/route.tsx b/frontend/src/pages/secret-manager/CommitDetailsPage/components/RollbackPreviewTab/route.tsx index d0d3aead0..f78b27b4e 100644 --- a/frontend/src/pages/secret-manager/CommitDetailsPage/components/RollbackPreviewTab/route.tsx +++ b/frontend/src/pages/secret-manager/CommitDetailsPage/components/RollbackPreviewTab/route.tsx @@ -12,7 +12,7 @@ const RollbackPreviewTabQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/$commitId/restore" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/restore" )({ component: RollbackPreviewTab, validateSearch: zodValidator(RollbackPreviewTabQueryParamsSchema), @@ -33,7 +33,7 @@ export const Route = createFileRoute( links: context.project.environments.map((el) => ({ label: el.name, link: linkOptions({ - to: "/projects/$projectId/secret-manager/secrets/$envSlug", + to: "/projects/secret-management/$projectId/secrets/$envSlug", params: { projectId: params.projectId, envSlug: el.slug @@ -56,7 +56,7 @@ export const Route = createFileRoute( { label: "Commits", link: linkOptions({ - to: "/projects/$projectId/secret-manager/commits/$environment/$folderId", + to: "/projects/secret-management/$projectId/commits/$environment/$folderId", params: { projectId: params.projectId, environment: params.environment, @@ -70,7 +70,7 @@ export const Route = createFileRoute( { label: params.commitId, link: linkOptions({ - to: "/projects/$projectId/secret-manager/commits/$environment/$folderId/$commitId", + to: "/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId", params: { projectId: params.projectId, environment: params.environment, diff --git a/frontend/src/pages/secret-manager/CommitDetailsPage/components/SecretVersionDiffView/SecretVersionDiffView.tsx b/frontend/src/pages/secret-manager/CommitDetailsPage/components/SecretVersionDiffView/SecretVersionDiffView.tsx index 7744d3626..789a17f0f 100644 --- a/frontend/src/pages/secret-manager/CommitDetailsPage/components/SecretVersionDiffView/SecretVersionDiffView.tsx +++ b/frontend/src/pages/secret-manager/CommitDetailsPage/components/SecretVersionDiffView/SecretVersionDiffView.tsx @@ -1,7 +1,10 @@ /* eslint-disable no-nested-ternary */ import { useCallback, useRef, useState } from "react"; -import { faChevronDown, faChevronUp } from "@fortawesome/free-solid-svg-icons"; +import { faChevronDown, faChevronUp, faTrash } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { twMerge } from "tailwind-merge"; + +import { IconButton, Tooltip } from "@app/components/v2"; export interface Version { id?: string; @@ -32,6 +35,7 @@ interface SecretVersionDiffViewProps { showHeader?: boolean; customHeader?: JSX.Element; excludedFieldsHighlight?: string[]; + onDiscard?: VoidFunction; } const isObject = (obj: JsonValue): obj is JsonObject => { @@ -225,15 +229,12 @@ const renderJsonWithDiffs = ( const getLineClass = (different: boolean) => { if (!different) return "flex"; - return isOldVersion ? "flex bg-red-950 text-red-300" : "flex bg-green-950 text-green-300"; + return isOldVersion + ? "flex bg-red-500/50 rounded-sm text-red-300" + : "flex bg-green-500/50 rounded-sm text-green-300"; }; - const getHighlightClass = (different: boolean) => { - if (!different) return ""; - return isOldVersion ? "bg-red-900 rounded px-1" : "bg-green-900 rounded px-1"; - }; - - const prefix = isDifferent ? (isOldVersion ? "-" : "+") : " "; + const prefix = isDifferent ? (isOldVersion ? " -" : " +") : " "; const keyDisplay = keyName ? `"${keyName}": ` : ""; const comma = !isLastItem ? "," : ""; @@ -255,8 +256,8 @@ const renderJsonWithDiffs = ( {prefix} {indent} - {keyName && {keyDisplay}} - {valueDisplay} + {keyName && {keyDisplay}} + {valueDisplay} {comma} @@ -269,8 +270,8 @@ const renderJsonWithDiffs = ( {prefix} {indent} - {keyName && {keyDisplay}} - [] + {keyName && {keyDisplay}} + [] {comma} @@ -283,8 +284,8 @@ const renderJsonWithDiffs = ( {prefix} {indent} - {keyName && {keyDisplay}} - {"{}"} + {keyName && {keyDisplay}} + {"{}"} {comma} @@ -320,16 +321,12 @@ const renderJsonWithDiffs = ( - {isContainerAddedOrRemoved ? (isOldVersion ? "-" : "+") : " "} + {isContainerAddedOrRemoved ? (isOldVersion ? " -" : " +") : " "} {indent} - {keyName && ( - - {keyDisplay} - - )} - [ + {keyName && {keyDisplay}} + [ @@ -357,11 +354,11 @@ const renderJsonWithDiffs = ( - {isContainerAddedOrRemoved ? (isOldVersion ? "-" : "+") : " "} + {isContainerAddedOrRemoved ? (isOldVersion ? " -" : " +") : " "} {indent} - ] + ] {comma} @@ -376,16 +373,12 @@ const renderJsonWithDiffs = ( - {isContainerAddedOrRemoved ? (isOldVersion ? "-" : "+") : " "} + {isContainerAddedOrRemoved ? (isOldVersion ? " -" : " +") : " "} {indent} - {keyName && ( - - {keyDisplay} - - )} - {"{"} + {keyName && {keyDisplay}} + {"{"} @@ -414,12 +407,11 @@ const renderJsonWithDiffs = ( - {isContainerAddedOrRemoved ? (isOldVersion ? "-" : "+") : " "} + {isContainerAddedOrRemoved ? (isOldVersion ? " -" : " +") : " "} {indent} - {"}"} - {comma} + {"}"} @@ -475,7 +467,9 @@ const formatDeletedJson = (json: JsonValue): JSX.Element => { const cleanVersionForComparison = (version: Version): JsonValue => { const { id, version: versionNumber, ...cleanVersion } = version; - return cleanVersion; + return Object.fromEntries( + Object.entries(cleanVersion).filter((entry) => typeof entry[1] !== "undefined") + ); }; export const SecretVersionDiffView = ({ @@ -484,7 +478,8 @@ export const SecretVersionDiffView = ({ onToggleCollapse, showHeader = true, customHeader, - excludedFieldsHighlight = ["metadata", "tags"] + excludedFieldsHighlight = ["metadata", "tags"], + onDiscard }: SecretVersionDiffViewProps) => { const oldContainerRef = useRef(null); const newContainerRef = useRef(null); @@ -527,7 +522,7 @@ export const SecretVersionDiffView = ({ } oldVersionContent = ( - + {renderJsonWithDiffs( cleanOldVersion, diffPaths, @@ -543,7 +538,7 @@ export const SecretVersionDiffView = ({ ); newVersionContent = ( - + {renderJsonWithDiffs( cleanNewVersion, diffPaths, @@ -583,19 +578,19 @@ export const SecretVersionDiffView = ({ if (item.isDeleted) { textStyle = "line-through text-red-300"; changeBadge = ( - + {isSecret ? "Secret" : "Folder"} Deleted ); } else if (item.isAdded) { changeBadge = ( - + {isSecret ? "Secret" : "Folder"} Added ); } else if (item.isUpdated) { changeBadge = ( - + {isSecret ? "Secret" : "Folder"} Updated ); @@ -615,32 +610,48 @@ export const SecretVersionDiffView = ({ tabIndex={0} aria-expanded={!collapsed} > - - {key} + + {key} {changeBadge} - + {onDiscard && ( + + + + + + )} + ); }; return ( - + {showHeader && renderHeader()} - {!collapsed && ( - - + + {oldVersionContent} - + {newVersionContent} diff --git a/frontend/src/pages/secret-manager/CommitDetailsPage/route.tsx b/frontend/src/pages/secret-manager/CommitDetailsPage/route.tsx index 623b42050..0cd791c27 100644 --- a/frontend/src/pages/secret-manager/CommitDetailsPage/route.tsx +++ b/frontend/src/pages/secret-manager/CommitDetailsPage/route.tsx @@ -12,7 +12,7 @@ const CommitDetailsPageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/$commitId/" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/" )({ component: CommitDetailsPage, validateSearch: zodValidator(CommitDetailsPageQueryParamsSchema), @@ -33,7 +33,7 @@ export const Route = createFileRoute( links: context.project.environments.map((el) => ({ label: el.name, link: linkOptions({ - to: "/projects/$projectId/secret-manager/secrets/$envSlug", + to: "/projects/secret-management/$projectId/secrets/$envSlug", params: { projectId: params.projectId, envSlug: el.slug @@ -56,7 +56,7 @@ export const Route = createFileRoute( { label: "Commits", link: linkOptions({ - to: "/projects/$projectId/secret-manager/commits/$environment/$folderId", + to: "/projects/secret-management/$projectId/commits/$environment/$folderId", params: { projectId: params.projectId, environment: params.environment, diff --git a/frontend/src/pages/secret-manager/CommitsPage/CommitsPage.tsx b/frontend/src/pages/secret-manager/CommitsPage/CommitsPage.tsx index 406a1b112..1acb76446 100644 --- a/frontend/src/pages/secret-manager/CommitsPage/CommitsPage.tsx +++ b/frontend/src/pages/secret-manager/CommitsPage/CommitsPage.tsx @@ -31,7 +31,7 @@ export const CommitsPage = () => { const handleSelectCommit = (commitId: string) => { navigate({ - to: "/projects/$projectId/secret-manager/commits/$environment/$folderId/$commitId", + to: "/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId", params: { projectId: currentWorkspace.id, folderId, @@ -52,7 +52,7 @@ export const CommitsPage = () => { title="Commits" description="Track, inspect, and restore your secrets and folders with confidence. View the complete history of changes made to your environment, examine specific modifications at each commit point, and preview the exact impact before rolling back to previous states." /> - + Secret Snapshots have been officially renamed to Commits. Going forward, all secret changes will be tracked as Commits. If you made changes before this update, you can diff --git a/frontend/src/pages/secret-manager/CommitsPage/components/CommitHistoryTab/CommitHistoryTab.tsx b/frontend/src/pages/secret-manager/CommitsPage/components/CommitHistoryTab/CommitHistoryTab.tsx index 8f529ba86..58191f389 100644 --- a/frontend/src/pages/secret-manager/CommitsPage/components/CommitHistoryTab/CommitHistoryTab.tsx +++ b/frontend/src/pages/secret-manager/CommitsPage/components/CommitHistoryTab/CommitHistoryTab.tsx @@ -1,29 +1,17 @@ -import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { useCallback, useEffect, useRef, useState } from "react"; import { faArrowDownWideShort, faArrowUpWideShort, + faCodeCommit, faCopy, faSearch } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { format, formatDistanceToNow } from "date-fns"; +import { formatDistanceToNow } from "date-fns"; -import { Button, Input, Spinner } from "@app/components/v2"; +import { Button, ContentLoader, EmptyState, IconButton, Input } from "@app/components/v2"; import { CopyButton } from "@app/components/v2/CopyButton"; -import { useGetFolderCommitHistory } from "@app/hooks/api/folderCommits"; - -interface CommitActorMetadata { - email?: string; - name?: string; -} - -interface Commit { - id: string; - message: string; - createdAt: string; - actorType: string; - actorMetadata?: CommitActorMetadata; -} +import { Commit, useGetFolderCommitHistory } from "@app/hooks/api/folderCommits"; const formatTimeAgo = (timestamp: string): string => { return formatDistanceToNow(new Date(timestamp), { addSuffix: true }); @@ -40,58 +28,40 @@ const CommitItem = ({ onSelectCommit: (commitId: string, tab: string) => void; }) => { return ( - - - - - - { - e.stopPropagation(); - onSelectCommit(commit.id, "tab-commit-details"); - }} - > - {commit.message} - - - - - {commit.actorMetadata?.email || commit.actorMetadata?.name || commit.actorType} - committed - {formatTimeAgo(commit.createdAt)} - - - - - - { - e.stopPropagation(); - onSelectCommit(commit.id, "tab-commit-details"); - }} - > - - {commit.id?.substring(0, 11)} - - - - - + { + e.stopPropagation(); + onSelectCommit(commit.id, "tab-commit-details"); + }} + className="w-full border border-b-0 border-mineshaft-600 bg-mineshaft-800 first:rounded-t-md last:rounded-b-md last:border-b" + > + + + + {commit.message} + + + {commit.actorMetadata?.email || commit.actorMetadata?.name || commit.actorType}{" "} + committed {formatTimeAgo(commit.createdAt)} + + + + + + {commit.id?.substring(0, 11)} + + - + ); }; @@ -108,24 +78,16 @@ const DateGroup = ({ onSelectCommit: (commitId: string, tab: string) => void; }) => { return ( - - - - - - - Commits on {date} + + + + Commits on {date} - - + {commits.map((commit) => ( - - - - - + ))} @@ -147,10 +109,8 @@ export const CommitHistoryTab = ({ const [searchTerm, setSearchTerm] = useState(""); const [debouncedSearchTerm, setDebouncedSearchTerm] = useState(""); const [sortDirection, setSortDirection] = useState<"asc" | "desc">("desc"); - const [offset, setOffset] = useState(0); - const [allCommits, setAllCommits] = useState([]); const debounceTimeoutRef = useRef(); - const limit = 5; + const limit = 10; // Debounce search term useEffect(() => { @@ -170,55 +130,20 @@ export const CommitHistoryTab = ({ }, [searchTerm]); const { - data: response, + data: groupedCommits, isLoading, - isFetching + fetchNextPage, + isFetchingNextPage, + hasNextPage } = useGetFolderCommitHistory({ workspaceId: projectId, environment, directory: secretPath, - offset, limit, search: debouncedSearchTerm, sort: sortDirection }); - const commits = response?.commits || []; - const hasMore = response?.hasMore || false; - - // Reset accumulated commits when search or sort changes - useEffect(() => { - setAllCommits([]); - setOffset(0); - }, [debouncedSearchTerm, sortDirection]); - - // Accumulate commits instead of replacing them - useEffect(() => { - if (commits.length > 0) { - if (offset === 0) { - // First load or after search/sort change - replace all commits - setAllCommits(commits); - } else { - // Subsequent loads - append new commits - setAllCommits((prev) => [...prev, ...commits]); - } - } - }, [commits, offset]); - - const groupedCommits = useMemo(() => { - return allCommits.reduce( - (acc, commit) => { - const date = format(new Date(commit.createdAt), "MMM d, yyyy"); - if (!acc[date]) { - acc[date] = []; - } - acc[date].push(commit); - return acc; - }, - {} as Record - ); - }, [allCommits]); - const handleSort = useCallback(() => { setSortDirection((prev) => (prev === "desc" ? "asc" : "desc")); }, []); @@ -227,50 +152,39 @@ export const CommitHistoryTab = ({ setSearchTerm(value); }, []); - const loadMoreCommits = useCallback(() => { - if (hasMore && !isFetching) { - setOffset((prev) => prev + limit); - } - }, [hasMore, isFetching, limit]); - return ( - + + Commit History } placeholder="Search commits..." - className="h-10 w-full rounded-md border-transparent bg-zinc-800 pl-9 pr-3 text-sm text-white placeholder-gray-400 focus:border-gray-600 focus:ring-primary-500/20" onChange={(e) => handleSearch(e.target.value)} value={searchTerm} aria-label="Search commits" /> - - - - - + - - {isLoading && offset === 0 ? ( - - - + {isLoading ? ( + ) : ( - - {Object.keys(groupedCommits).length > 0 ? ( + + {groupedCommits && Object.keys(groupedCommits).length > 0 ? ( <> {Object.entries(groupedCommits).map(([date, dateCommits]) => ( ) : ( - - - No matching commits found. Try a different search term. - + )} - - {hasMore && ( + {hasNextPage && ( fetchNextPage()} + disabled={isFetchingNextPage} + isLoading={isFetchingNextPage} aria-label="Load more commits" > - {isFetching ? ( - <> - - Loading... - > - ) : ( - "Load more commits" - )} + Load More Commits )} diff --git a/frontend/src/pages/secret-manager/CommitsPage/route.tsx b/frontend/src/pages/secret-manager/CommitsPage/route.tsx index e98fcc842..0e3cbb80a 100644 --- a/frontend/src/pages/secret-manager/CommitsPage/route.tsx +++ b/frontend/src/pages/secret-manager/CommitsPage/route.tsx @@ -13,7 +13,7 @@ const CommitsPageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/" )({ component: CommitsPage, validateSearch: zodValidator(CommitsPageQueryParamsSchema), @@ -34,7 +34,7 @@ export const Route = createFileRoute( links: context.project.environments.map((el) => ({ label: el.name, link: linkOptions({ - to: "/projects/$projectId/secret-manager/secrets/$envSlug", + to: "/projects/secret-management/$projectId/secrets/$envSlug", params: { projectId: params.projectId, envSlug: el.slug @@ -57,7 +57,7 @@ export const Route = createFileRoute( { label: "Commits", link: linkOptions({ - to: "/projects/$projectId/secret-manager/commits/$environment/$folderId", + to: "/projects/secret-management/$projectId/commits/$environment/$folderId", params: { projectId: params.projectId, environment: params.environment, diff --git a/frontend/src/pages/secret-manager/IPAllowlistPage/route.tsx b/frontend/src/pages/secret-manager/IPAllowlistPage/route.tsx index 16ede0811..639289de2 100644 --- a/frontend/src/pages/secret-manager/IPAllowlistPage/route.tsx +++ b/frontend/src/pages/secret-manager/IPAllowlistPage/route.tsx @@ -3,7 +3,7 @@ import { createFileRoute } from "@tanstack/react-router"; import { IPAllowListPage } from "./IPAllowlistPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/allowlist" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/allowlist" )({ component: () => IPAllowListPage }); diff --git a/frontend/src/pages/secret-manager/IntegrationsDetailsByIDPage/route.tsx b/frontend/src/pages/secret-manager/IntegrationsDetailsByIDPage/route.tsx index 424835421..29627c5a7 100644 --- a/frontend/src/pages/secret-manager/IntegrationsDetailsByIDPage/route.tsx +++ b/frontend/src/pages/secret-manager/IntegrationsDetailsByIDPage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { IntegrationDetailsByIDPage } from "./IntegrationsDetailsByIDPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/$integrationId" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/$integrationId" )({ component: IntegrationDetailsByIDPage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/IntegrationsListPage/IntegrationsListPage.utils.tsx b/frontend/src/pages/secret-manager/IntegrationsListPage/IntegrationsListPage.utils.tsx index 4120a3da3..25c12adc2 100644 --- a/frontend/src/pages/secret-manager/IntegrationsListPage/IntegrationsListPage.utils.tsx +++ b/frontend/src/pages/secret-manager/IntegrationsListPage/IntegrationsListPage.utils.tsx @@ -42,7 +42,7 @@ export const redirectForProviderAuth = ( switch (integrationOption.slug) { case "gcp-secret-manager": navigate({ - to: "/projects/$projectId/secret-manager/integrations/gcp-secret-manager/authorize", + to: "/projects/secret-management/$projectId/integrations/gcp-secret-manager/authorize", params: { projectId } @@ -54,7 +54,7 @@ export const redirectForProviderAuth = ( return; } navigate({ - to: "/projects/$projectId/secret-manager/integrations/azure-key-vault/authorize", + to: "/projects/secret-management/$projectId/integrations/azure-key-vault/authorize", params: { projectId }, @@ -76,7 +76,7 @@ export const redirectForProviderAuth = ( } case "aws-parameter-store": navigate({ - to: "/projects/$projectId/secret-manager/integrations/aws-parameter-store/authorize", + to: "/projects/secret-management/$projectId/integrations/aws-parameter-store/authorize", params: { projectId } @@ -84,7 +84,7 @@ export const redirectForProviderAuth = ( break; case "aws-secret-manager": navigate({ - to: "/projects/$projectId/secret-manager/integrations/aws-secret-manager/authorize", + to: "/projects/secret-management/$projectId/integrations/aws-secret-manager/authorize", params: { projectId } @@ -120,7 +120,7 @@ export const redirectForProviderAuth = ( } case "github": navigate({ - to: "/projects/$projectId/secret-manager/integrations/github/auth-mode-selection", + to: "/projects/secret-management/$projectId/integrations/github/auth-mode-selection", params: { projectId } @@ -128,7 +128,7 @@ export const redirectForProviderAuth = ( break; case "gitlab": navigate({ - to: "/projects/$projectId/secret-manager/integrations/gitlab/authorize", + to: "/projects/secret-management/$projectId/integrations/gitlab/authorize", params: { projectId } @@ -136,7 +136,7 @@ export const redirectForProviderAuth = ( break; case "render": navigate({ - to: "/projects/$projectId/secret-manager/integrations/render/authorize", + to: "/projects/secret-management/$projectId/integrations/render/authorize", params: { projectId } @@ -144,7 +144,7 @@ export const redirectForProviderAuth = ( break; case "flyio": navigate({ - to: "/projects/$projectId/secret-manager/integrations/flyio/authorize", + to: "/projects/secret-management/$projectId/integrations/flyio/authorize", params: { projectId } @@ -152,7 +152,7 @@ export const redirectForProviderAuth = ( break; case "circleci": navigate({ - to: "/projects/$projectId/secret-manager/integrations/circleci/authorize", + to: "/projects/secret-management/$projectId/integrations/circleci/authorize", params: { projectId } @@ -160,7 +160,7 @@ export const redirectForProviderAuth = ( break; case "databricks": navigate({ - to: "/projects/$projectId/secret-manager/integrations/databricks/authorize", + to: "/projects/secret-management/$projectId/integrations/databricks/authorize", params: { projectId } @@ -168,7 +168,7 @@ export const redirectForProviderAuth = ( break; case "laravel-forge": navigate({ - to: "/projects/$projectId/secret-manager/integrations/laravel-forge/authorize", + to: "/projects/secret-management/$projectId/integrations/laravel-forge/authorize", params: { projectId } @@ -176,7 +176,7 @@ export const redirectForProviderAuth = ( break; case "travisci": navigate({ - to: "/projects/$projectId/secret-manager/integrations/travisci/authorize", + to: "/projects/secret-management/$projectId/integrations/travisci/authorize", params: { projectId } @@ -184,7 +184,7 @@ export const redirectForProviderAuth = ( break; case "supabase": navigate({ - to: "/projects/$projectId/secret-manager/integrations/supabase/authorize", + to: "/projects/secret-management/$projectId/integrations/supabase/authorize", params: { projectId } @@ -192,7 +192,7 @@ export const redirectForProviderAuth = ( break; case "checkly": navigate({ - to: "/projects/$projectId/secret-manager/integrations/checkly/authorize", + to: "/projects/secret-management/$projectId/integrations/checkly/authorize", params: { projectId } @@ -200,7 +200,7 @@ export const redirectForProviderAuth = ( break; case "qovery": navigate({ - to: "/projects/$projectId/secret-manager/integrations/qovery/authorize", + to: "/projects/secret-management/$projectId/integrations/qovery/authorize", params: { projectId } @@ -208,7 +208,7 @@ export const redirectForProviderAuth = ( break; case "railway": navigate({ - to: "/projects/$projectId/secret-manager/integrations/railway/authorize", + to: "/projects/secret-management/$projectId/integrations/railway/authorize", params: { projectId } @@ -216,7 +216,7 @@ export const redirectForProviderAuth = ( break; case "terraform-cloud": navigate({ - to: "/projects/$projectId/secret-manager/integrations/terraform-cloud/authorize", + to: "/projects/secret-management/$projectId/integrations/terraform-cloud/authorize", params: { projectId } @@ -224,7 +224,7 @@ export const redirectForProviderAuth = ( break; case "hashicorp-vault": navigate({ - to: "/projects/$projectId/secret-manager/integrations/hashicorp-vault/authorize", + to: "/projects/secret-management/$projectId/integrations/hashicorp-vault/authorize", params: { projectId } @@ -232,7 +232,7 @@ export const redirectForProviderAuth = ( break; case "cloudflare-pages": navigate({ - to: "/projects/$projectId/secret-manager/integrations/cloudflare-pages/authorize", + to: "/projects/secret-management/$projectId/integrations/cloudflare-pages/authorize", params: { projectId } @@ -240,7 +240,7 @@ export const redirectForProviderAuth = ( break; case "cloudflare-workers": navigate({ - to: "/projects/$projectId/secret-manager/integrations/cloudflare-workers/authorize", + to: "/projects/secret-management/$projectId/integrations/cloudflare-workers/authorize", params: { projectId } @@ -257,7 +257,7 @@ export const redirectForProviderAuth = ( } case "codefresh": navigate({ - to: "/projects/$projectId/secret-manager/integrations/codefresh/authorize", + to: "/projects/secret-management/$projectId/integrations/codefresh/authorize", params: { projectId } @@ -265,7 +265,7 @@ export const redirectForProviderAuth = ( break; case "digital-ocean-app-platform": navigate({ - to: "/projects/$projectId/secret-manager/integrations/digital-ocean-app-platform/authorize", + to: "/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/authorize", params: { projectId } @@ -273,7 +273,7 @@ export const redirectForProviderAuth = ( break; case "cloud-66": navigate({ - to: "/projects/$projectId/secret-manager/integrations/cloud-66/authorize", + to: "/projects/secret-management/$projectId/integrations/cloud-66/authorize", params: { projectId } @@ -281,7 +281,7 @@ export const redirectForProviderAuth = ( break; case "northflank": navigate({ - to: "/projects/$projectId/secret-manager/integrations/northflank/authorize", + to: "/projects/secret-management/$projectId/integrations/northflank/authorize", params: { projectId } @@ -289,7 +289,7 @@ export const redirectForProviderAuth = ( break; case "windmill": navigate({ - to: "/projects/$projectId/secret-manager/integrations/windmill/authorize", + to: "/projects/secret-management/$projectId/integrations/windmill/authorize", params: { projectId } @@ -297,7 +297,7 @@ export const redirectForProviderAuth = ( break; case "teamcity": navigate({ - to: "/projects/$projectId/secret-manager/integrations/teamcity/authorize", + to: "/projects/secret-management/$projectId/integrations/teamcity/authorize", params: { projectId } @@ -305,7 +305,7 @@ export const redirectForProviderAuth = ( break; case "hasura-cloud": navigate({ - to: "/projects/$projectId/secret-manager/integrations/hasura-cloud/authorize", + to: "/projects/secret-management/$projectId/integrations/hasura-cloud/authorize", params: { projectId } @@ -313,7 +313,7 @@ export const redirectForProviderAuth = ( break; case "rundeck": navigate({ - to: "/projects/$projectId/secret-manager/integrations/rundeck/authorize", + to: "/projects/secret-management/$projectId/integrations/rundeck/authorize", params: { projectId } @@ -321,7 +321,7 @@ export const redirectForProviderAuth = ( break; case "azure-devops": navigate({ - to: "/projects/$projectId/secret-manager/integrations/azure-devops/authorize", + to: "/projects/secret-management/$projectId/integrations/azure-devops/authorize", params: { projectId } @@ -329,7 +329,7 @@ export const redirectForProviderAuth = ( break; case "octopus-deploy": navigate({ - to: "/projects/$projectId/secret-manager/integrations/octopus-deploy/authorize", + to: "/projects/secret-management/$projectId/integrations/octopus-deploy/authorize", params: { projectId } diff --git a/frontend/src/pages/secret-manager/IntegrationsListPage/components/NativeIntegrationsTab/IntegrationRow.tsx b/frontend/src/pages/secret-manager/IntegrationsListPage/components/NativeIntegrationsTab/IntegrationRow.tsx index 194c543d2..df862b8ba 100644 --- a/frontend/src/pages/secret-manager/IntegrationsListPage/components/NativeIntegrationsTab/IntegrationRow.tsx +++ b/frontend/src/pages/secret-manager/IntegrationsListPage/components/NativeIntegrationsTab/IntegrationRow.tsx @@ -59,7 +59,7 @@ export const IntegrationRow = ({ navigate({ - to: "/projects/$projectId/secret-manager/integrations/$integrationId", + to: "/projects/secret-management/$projectId/integrations/$integrationId", params: { integrationId: integration.id, projectId: currentWorkspace.id diff --git a/frontend/src/pages/secret-manager/IntegrationsListPage/components/SecretSyncsTab/SecretSyncTable/SecretSyncDestinationCol/BitbucketSyncDestinationCol.tsx b/frontend/src/pages/secret-manager/IntegrationsListPage/components/SecretSyncsTab/SecretSyncTable/SecretSyncDestinationCol/BitbucketSyncDestinationCol.tsx new file mode 100644 index 000000000..80243daec --- /dev/null +++ b/frontend/src/pages/secret-manager/IntegrationsListPage/components/SecretSyncsTab/SecretSyncTable/SecretSyncDestinationCol/BitbucketSyncDestinationCol.tsx @@ -0,0 +1,14 @@ +import { TBitbucketSync } from "@app/hooks/api/secretSyncs/types/bitbucket-sync"; + +import { getSecretSyncDestinationColValues } from "../helpers"; +import { SecretSyncTableCell } from "../SecretSyncTableCell"; + +type Props = { + secretSync: TBitbucketSync; +}; + +export const BitbucketSyncDestinationCol = ({ secretSync }: Props) => { + const { primaryText, secondaryText } = getSecretSyncDestinationColValues(secretSync); + + return ; +}; diff --git a/frontend/src/pages/secret-manager/IntegrationsListPage/components/SecretSyncsTab/SecretSyncTable/SecretSyncDestinationCol/SecretSyncDestinationCol.tsx b/frontend/src/pages/secret-manager/IntegrationsListPage/components/SecretSyncsTab/SecretSyncTable/SecretSyncDestinationCol/SecretSyncDestinationCol.tsx index 0a41b2c4b..10ffa9e8c 100644 --- a/frontend/src/pages/secret-manager/IntegrationsListPage/components/SecretSyncsTab/SecretSyncTable/SecretSyncDestinationCol/SecretSyncDestinationCol.tsx +++ b/frontend/src/pages/secret-manager/IntegrationsListPage/components/SecretSyncsTab/SecretSyncTable/SecretSyncDestinationCol/SecretSyncDestinationCol.tsx @@ -6,6 +6,7 @@ import { AwsSecretsManagerSyncDestinationCol } from "./AwsSecretsManagerSyncDest import { AzureAppConfigurationDestinationSyncCol } from "./AzureAppConfigurationDestinationSyncCol"; import { AzureDevOpsSyncDestinationCol } from "./AzureDevOpsSyncDestinationCol"; import { AzureKeyVaultDestinationSyncCol } from "./AzureKeyVaultDestinationSyncCol"; +import { BitbucketSyncDestinationCol } from "./BitbucketSyncDestinationCol"; import { CamundaSyncDestinationCol } from "./CamundaSyncDestinationCol"; import { ChecklySyncDestinationCol } from "./ChecklySyncDestinationCol"; import { CloudflarePagesSyncDestinationCol } from "./CloudflarePagesSyncDestinationCol"; @@ -88,6 +89,8 @@ export const SecretSyncDestinationCol = ({ secretSync }: Props) => { return ; case SecretSync.Supabase: return ; + case SecretSync.Bitbucket: + return ; default: throw new Error( `Unhandled Secret Sync Destination Col: ${(secretSync as TSecretSync).destination}` diff --git a/frontend/src/pages/secret-manager/IntegrationsListPage/components/SecretSyncsTab/SecretSyncTable/helpers/index.ts b/frontend/src/pages/secret-manager/IntegrationsListPage/components/SecretSyncsTab/SecretSyncTable/helpers/index.ts index a4a7e5480..e8d95344b 100644 --- a/frontend/src/pages/secret-manager/IntegrationsListPage/components/SecretSyncsTab/SecretSyncTable/helpers/index.ts +++ b/frontend/src/pages/secret-manager/IntegrationsListPage/components/SecretSyncsTab/SecretSyncTable/helpers/index.ts @@ -174,6 +174,10 @@ export const getSecretSyncDestinationColValues = (secretSync: TSecretSync) => { primaryText = destinationConfig.projectName; secondaryText = "Supabase Project"; break; + case SecretSync.Bitbucket: + primaryText = destinationConfig.workspaceSlug; + secondaryText = destinationConfig.repositorySlug; + break; default: throw new Error(`Unhandled Destination Col Values ${destination}`); } diff --git a/frontend/src/pages/secret-manager/IntegrationsListPage/route.tsx b/frontend/src/pages/secret-manager/IntegrationsListPage/route.tsx index c59956459..b7f8236da 100644 --- a/frontend/src/pages/secret-manager/IntegrationsListPage/route.tsx +++ b/frontend/src/pages/secret-manager/IntegrationsListPage/route.tsx @@ -21,7 +21,7 @@ const IntegrationsListPageQuerySchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/" )({ component: IntegrationsListPage, validateSearch: zodValidator(IntegrationsListPageQuerySchema), @@ -36,7 +36,7 @@ export const Route = createFileRoute( }); } catch { throw redirect({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId }, @@ -46,7 +46,7 @@ export const Route = createFileRoute( if (secretSyncs.length) { throw redirect({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId }, @@ -62,7 +62,7 @@ export const Route = createFileRoute( }); } catch { throw redirect({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId }, @@ -72,7 +72,7 @@ export const Route = createFileRoute( if (integrations.length) { throw redirect({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId }, @@ -81,7 +81,7 @@ export const Route = createFileRoute( } throw redirect({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId }, diff --git a/frontend/src/pages/secret-manager/OverviewPage/OverviewPage.tsx b/frontend/src/pages/secret-manager/OverviewPage/OverviewPage.tsx index f58edbd33..61be72832 100644 --- a/frontend/src/pages/secret-manager/OverviewPage/OverviewPage.tsx +++ b/frontend/src/pages/secret-manager/OverviewPage/OverviewPage.tsx @@ -667,7 +667,7 @@ export const OverviewPage = () => { const envIndex = visibleEnvs.findIndex((el) => slug === el.slug); if (envIndex !== -1) { navigate({ - to: "/projects/$projectId/secret-manager/secrets/$envSlug", + to: "/projects/secret-management/$projectId/secrets/$envSlug", params: { projectId: workspaceId, envSlug: slug @@ -1420,7 +1420,7 @@ export const OverviewPage = () => { iconSize="3x" > { const navigate = useNavigate({ - from: "/projects/$projectId/secret-manager/overview" + from: "/projects/secret-management/$projectId/overview" }); const onFolderCrumbClick = (index: number) => { diff --git a/frontend/src/pages/secret-manager/OverviewPage/components/SecretSearchInput/components/QuickSearchDynamicSecretItem.tsx b/frontend/src/pages/secret-manager/OverviewPage/components/SecretSearchInput/components/QuickSearchDynamicSecretItem.tsx index 0d01370d4..79911b6ee 100644 --- a/frontend/src/pages/secret-manager/OverviewPage/components/SecretSearchInput/components/QuickSearchDynamicSecretItem.tsx +++ b/frontend/src/pages/secret-manager/OverviewPage/components/SecretSearchInput/components/QuickSearchDynamicSecretItem.tsx @@ -17,7 +17,7 @@ export const QuickSearchDynamicSecretItem = ({ onClose }: Props) => { const navigate = useNavigate({ - from: "/projects/$projectId/secret-manager/overview" + from: "/projects/secret-management/$projectId/overview" }); const [groupDynamicSecret] = dynamicSecretGroup; diff --git a/frontend/src/pages/secret-manager/OverviewPage/components/SecretSearchInput/components/QuickSearchFolderItem.tsx b/frontend/src/pages/secret-manager/OverviewPage/components/SecretSearchInput/components/QuickSearchFolderItem.tsx index 77f1f5215..92d2fac3e 100644 --- a/frontend/src/pages/secret-manager/OverviewPage/components/SecretSearchInput/components/QuickSearchFolderItem.tsx +++ b/frontend/src/pages/secret-manager/OverviewPage/components/SecretSearchInput/components/QuickSearchFolderItem.tsx @@ -13,7 +13,7 @@ type Props = { export const QuickSearchFolderItem = ({ folderGroup, onClose }: Props) => { const navigate = useNavigate({ - from: "/projects/$projectId/secret-manager/overview" + from: "/projects/secret-management/$projectId/overview" }); const [groupFolder] = folderGroup; diff --git a/frontend/src/pages/secret-manager/OverviewPage/components/SecretSearchInput/components/QuickSearchSecretItem.tsx b/frontend/src/pages/secret-manager/OverviewPage/components/SecretSearchInput/components/QuickSearchSecretItem.tsx index c7a84f627..80b53d426 100644 --- a/frontend/src/pages/secret-manager/OverviewPage/components/SecretSearchInput/components/QuickSearchSecretItem.tsx +++ b/frontend/src/pages/secret-manager/OverviewPage/components/SecretSearchInput/components/QuickSearchSecretItem.tsx @@ -46,7 +46,7 @@ export const QuickSearchSecretItem = ({ isSingleEnv, search }: Props) => { - const navigate = useNavigate({ from: "/projects/$projectId/secret-manager/overview" }); + const navigate = useNavigate({ from: "/projects/secret-management/$projectId/overview" }); const envSlugMap = new Map(environments.map((env) => [env.slug, env])); const [isUrlCopied, , setIsUrlCopied] = useTimedReset({ initialState: false diff --git a/frontend/src/pages/secret-manager/OverviewPage/components/SecretSearchInput/components/QuickSearchSecretRotationItem.tsx b/frontend/src/pages/secret-manager/OverviewPage/components/SecretSearchInput/components/QuickSearchSecretRotationItem.tsx index 84869c656..fc4b66978 100644 --- a/frontend/src/pages/secret-manager/OverviewPage/components/SecretSearchInput/components/QuickSearchSecretRotationItem.tsx +++ b/frontend/src/pages/secret-manager/OverviewPage/components/SecretSearchInput/components/QuickSearchSecretRotationItem.tsx @@ -13,7 +13,7 @@ type Props = { export const QuickSearchSecretRotationItem = ({ secretRotationGroup, onClose }: Props) => { const navigate = useNavigate({ - from: "/projects/$projectId/secret-manager/overview" + from: "/projects/secret-management/$projectId/overview" }); const [groupSecretRotation] = secretRotationGroup; diff --git a/frontend/src/pages/secret-manager/OverviewPage/components/utils/index.ts b/frontend/src/pages/secret-manager/OverviewPage/components/utils/index.ts index 4441d842a..43caf7aa0 100644 --- a/frontend/src/pages/secret-manager/OverviewPage/components/utils/index.ts +++ b/frontend/src/pages/secret-manager/OverviewPage/components/utils/index.ts @@ -1,6 +1,6 @@ export const getExpandedRowStyle = (scrollOffset: number) => ({ marginLeft: scrollOffset, - width: "calc(100vw - 355px)", // 350px accounts for sidebar and margin + width: "calc(100vw - 275px)", // accounts for sidebar and margin maxWidth: "1270px" // largest width of table on ultra-wide }); diff --git a/frontend/src/pages/secret-manager/OverviewPage/route.tsx b/frontend/src/pages/secret-manager/OverviewPage/route.tsx index 66b57d547..968286e13 100644 --- a/frontend/src/pages/secret-manager/OverviewPage/route.tsx +++ b/frontend/src/pages/secret-manager/OverviewPage/route.tsx @@ -10,7 +10,7 @@ const SecretOverviewPageQuerySchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/overview" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/overview" )({ component: OverviewPage, validateSearch: zodValidator(SecretOverviewPageQuerySchema), @@ -24,7 +24,7 @@ export const Route = createFileRoute( { label: "Secrets", link: linkOptions({ - to: "/projects/$projectId/secret-manager/overview", + to: "/projects/secret-management/$projectId/overview", params }) } diff --git a/frontend/src/pages/secret-manager/SecretApprovalsPage/components/SecretApprovalRequest/components/SecretApprovalRequestChangeItem.tsx b/frontend/src/pages/secret-manager/SecretApprovalsPage/components/SecretApprovalRequest/components/SecretApprovalRequestChangeItem.tsx index 430ec8492..7fd050b03 100644 --- a/frontend/src/pages/secret-manager/SecretApprovalsPage/components/SecretApprovalRequest/components/SecretApprovalRequestChangeItem.tsx +++ b/frontend/src/pages/secret-manager/SecretApprovalsPage/components/SecretApprovalRequest/components/SecretApprovalRequestChangeItem.tsx @@ -156,11 +156,11 @@ export const SecretApprovalRequestChangeItem = ({ Tags - + {(secretVersion?.tags?.length ?? 0) ? ( secretVersion?.tags?.map(({ slug, id: tagId, color }) => ( - {Boolean(text.length) && "and"} + {Boolean(text.length) && " and "} {score[CommitType.DELETE]} Secret{score[CommitType.DELETE] !== 1 && "s"} Deleted diff --git a/frontend/src/pages/secret-manager/SecretApprovalsPage/route.tsx b/frontend/src/pages/secret-manager/SecretApprovalsPage/route.tsx index abeb64951..dfc6d4e4d 100644 --- a/frontend/src/pages/secret-manager/SecretApprovalsPage/route.tsx +++ b/frontend/src/pages/secret-manager/SecretApprovalsPage/route.tsx @@ -9,7 +9,7 @@ const SecretApprovalPageQueryParams = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/approval" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/approval" )({ component: SecretApprovalsPage, validateSearch: zodValidator(SecretApprovalPageQueryParams), diff --git a/frontend/src/pages/secret-manager/SecretDashboardPage/SecretDashboardPage.tsx b/frontend/src/pages/secret-manager/SecretDashboardPage/SecretDashboardPage.tsx index 1c95a202f..3342f6688 100644 --- a/frontend/src/pages/secret-manager/SecretDashboardPage/SecretDashboardPage.tsx +++ b/frontend/src/pages/secret-manager/SecretDashboardPage/SecretDashboardPage.tsx @@ -1,3 +1,4 @@ +/* eslint-disable no-case-declarations */ import { useCallback, useEffect, useMemo, useState } from "react"; import { Helmet } from "react-helmet"; import { useTranslation } from "react-i18next"; @@ -48,6 +49,9 @@ import { useGetProjectSecretsDetails } from "@app/hooks/api/dashboard"; import { DashboardSecretsOrderBy } from "@app/hooks/api/dashboard/types"; import { useGetFolderCommitsCount } from "@app/hooks/api/folderCommits"; import { OrderByDirection } from "@app/hooks/api/generic/types"; +import { PendingAction } from "@app/hooks/api/secretFolders/types"; +import { useCreateCommit } from "@app/hooks/api/secrets/mutations"; +import { SecretV3RawSanitized } from "@app/hooks/api/types"; import { usePathAccessPolicies } from "@app/hooks/usePathAccessPolicies"; import { hasSecretReadValueOrDescribePermission } from "@app/lib/fn/permission"; import { RequestAccessModal } from "@app/pages/secret-manager/SecretApprovalsPage/components/AccessApprovalRequest/components/RequestAccessModal"; @@ -56,6 +60,7 @@ import { SecretRotationListView } from "@app/pages/secret-manager/SecretDashboar import { SecretTableResourceCount } from "../OverviewPage/components/SecretTableResourceCount"; import { SecretV2MigrationSection } from "../OverviewPage/components/SecretV2MigrationSection"; import { ActionBar } from "./components/ActionBar"; +import { CommitForm } from "./components/CommitForm"; import { CreateSecretForm } from "./components/CreateSecretForm"; import { DynamicSecretListView } from "./components/DynamicSecretListView"; import { FolderListView } from "./components/FolderListView"; @@ -65,8 +70,11 @@ import { SecretImportListView } from "./components/SecretImportListView"; import { SecretListView, SecretNoAccessListView } from "./components/SecretListView"; import { SnapshotView } from "./components/SnapshotView"; import { + PendingChanges, PopUpNames, StoreProvider, + useBatchMode, + useBatchModeActions, usePopUpAction, usePopUpState, useSelectedSecretActions, @@ -94,8 +102,11 @@ const Page = () => { }); const { permission } = useProjectPermission(); + const { mutateAsync: createCommit } = useCreateCommit(); const [isVisible, setIsVisible] = useState(false); + const { isBatchMode, pendingChanges } = useBatchMode(); + const { loadPendingChanges, setExistingKeys } = useBatchModeActions(); const { offset, @@ -128,6 +139,12 @@ const Page = () => { const projectSlug = currentWorkspace?.slug || ""; const secretPath = (routerQueryParams.secretPath as string) || "/"; + useEffect(() => { + if (isBatchMode && workspaceId && environment && secretPath) { + loadPendingChanges({ workspaceId, environment, secretPath }); + } + }, [isBatchMode, workspaceId, environment, secretPath, loadPendingChanges]); + const canReadSecret = hasSecretReadValueOrDescribePermission( permission, ProjectPermissionSecretActions.DescribeSecret, @@ -217,7 +234,7 @@ const Page = () => { type: "error" }); navigate({ - to: "/projects/$projectId/secret-manager/overview", + to: "/projects/secret-management/$projectId/overview", params: { projectId: workspaceId } @@ -293,6 +310,30 @@ const Page = () => { }); const isProtectedBranch = Boolean(boardPolicy); + const handleCreateCommit = async (changes: PendingChanges, message: string) => { + try { + await createCommit({ + workspaceId, + environment, + secretPath, + pendingChanges: changes, + message + }); + createNotification({ + text: isProtectedBranch + ? "Requested changes have been sent for review" + : "Changes committed successfully", + type: "success" + }); + } catch (error) { + createNotification({ + text: "Failed to commit changes", + type: "error" + }); + console.error(error); + } + }; + const { data: snapshotList, isFetchingNextPage: isFetchingNextSnapshotList, @@ -345,7 +386,7 @@ const Page = () => { const handleOnClickRollbackMode = () => { if (isPITEnabled) { navigate({ - to: "/projects/$projectId/secret-manager/commits/$environment/$folderId", + to: "/projects/secret-management/$projectId/commits/$environment/$folderId", params: { projectId: workspaceId, folderId, @@ -376,9 +417,21 @@ const Page = () => { imports?.length || dynamicSecrets?.length || secretRotations?.length || - noAccessSecretCount + noAccessSecretCount || + pendingChanges.secrets.length || + pendingChanges.folders.length ); + useEffect(() => { + if (data && isBatchMode) { + const existingSecretKeys = [...(secrets?.map((s) => s.key) || [])]; + + const existingFolderNames = folders?.map((f) => f.name) || []; + + setExistingKeys(existingSecretKeys, existingFolderNames); + } + }, [data, isBatchMode, setExistingKeys, secrets, importedSecrets, folders]); + const handleSortToggle = () => setOrderDirection((state) => state === OrderByDirection.ASC ? OrderByDirection.DESC : OrderByDirection.ASC @@ -506,6 +559,143 @@ const Page = () => { setDebouncedSearchFilter(""); }; + const getMergedSecretsWithPending = () => { + if (!isBatchMode || pendingChanges.secrets.length === 0) { + return secrets; + } + + const mergedSecrets = [...(secrets || [])]; + + pendingChanges.secrets.forEach((change) => { + switch (change.type) { + case PendingAction.Create: + mergedSecrets.unshift({ + id: change.id, + key: change.secretKey, + value: change.secretValue, + comment: change.secretComment || "", + skipMultilineEncoding: change.skipMultilineEncoding || false, + tags: change.tags || [], + secretMetadata: change.secretMetadata || [], + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + version: 1, + isPending: true, + pendingAction: PendingAction.Create + } as unknown as SecretV3RawSanitized); + break; + + case PendingAction.Update: + const updateIndex = mergedSecrets.findIndex((s) => s.key === change.secretKey); + if (updateIndex >= 0) { + mergedSecrets[updateIndex] = { + ...mergedSecrets[updateIndex], + key: change.newSecretName || change.secretKey, + value: + change.secretValue !== undefined + ? change.secretValue + : mergedSecrets[updateIndex].value, + comment: + change.secretComment !== undefined + ? change.secretComment + : mergedSecrets[updateIndex].comment, + skipMultilineEncoding: + change.skipMultilineEncoding !== undefined + ? change.skipMultilineEncoding + : mergedSecrets[updateIndex].skipMultilineEncoding, + secretMetadata: change.secretMetadata || mergedSecrets[updateIndex].secretMetadata, + isPending: true, + pendingAction: PendingAction.Update, + tags: change.tags + ? change.tags?.map((tag) => ({ + id: tag.id, + slug: tag.slug, + projectId: workspaceId, + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + __v: 0 + })) || [] + : mergedSecrets[updateIndex].tags + }; + } + break; + + case PendingAction.Delete: + const deleteIndex = mergedSecrets.findIndex((s) => s.key === change.secretKey); + if (deleteIndex >= 0) { + mergedSecrets[deleteIndex] = { + ...mergedSecrets[deleteIndex], + isPending: true, + pendingAction: PendingAction.Delete + }; + } + break; + + default: + break; + } + }); + + return mergedSecrets; + }; + + const getMergedFoldersWithPending = () => { + if (!isBatchMode || pendingChanges.folders.length === 0) { + return folders; + } + + const mergedFolders = [...(folders || [])]; + + pendingChanges.folders.forEach((change) => { + switch (change.type) { + case PendingAction.Create: + mergedFolders.unshift({ + id: change.id, + name: change.folderName, + description: change.description, + parentId: null, + isPending: true, + pendingAction: PendingAction.Create + } as any); + break; + + case PendingAction.Update: + const updateIndex = mergedFolders.findIndex((f) => f.id === change.id); + if (updateIndex >= 0) { + mergedFolders[updateIndex] = { + ...mergedFolders[updateIndex], + name: change.folderName, + description: + change.description !== undefined + ? change.description + : mergedFolders[updateIndex].description, + isPending: true, + pendingAction: PendingAction.Update + }; + } + break; + + case PendingAction.Delete: + const deleteIndex = mergedFolders.findIndex((f) => f.id === change.id); + if (deleteIndex >= 0) { + mergedFolders[deleteIndex] = { + ...mergedFolders[deleteIndex], + isPending: true, + pendingAction: PendingAction.Delete + }; + } + break; + + default: + break; + } + }); + + return mergedFolders; + }; + + const mergedSecrets = getMergedSecretsWithPending(); + const mergedFolders = getMergedFoldersWithPending(); return ( { projectSlug={projectSlug} secretPath={secretPath} isVisible={isVisible} + isBatchMode={isBatchMode} filter={filter} tags={tags} onVisibilityToggle={handleToggleVisibility} @@ -698,9 +889,9 @@ const Page = () => { importedSecrets={importedSecrets} /> )} - {Boolean(folders?.length) && ( + {Boolean(mergedFolders?.length) && ( { {canReadSecretRotations && Boolean(secretRotations?.length) && ( )} - {canReadSecret && Boolean(secrets?.length) && ( + {canReadSecret && Boolean(mergedSecrets?.length) && ( { usedBySecretSyncs={usedBySecretSyncs} /> )} + {(pendingChanges.secrets.length > 0 || pendingChanges.folders.length > 0) && ( + + )} {noAccessSecretCount > 0 && } {!canReadSecret && !canReadDynamicSecret && @@ -738,25 +938,34 @@ const Page = () => { folders?.length === 0 && } - {!isDetailsLoading && totalCount > 0 && ( - - } - className="rounded-b-md border-t border-solid border-t-mineshaft-600" - count={totalCount} - page={page} - perPage={perPage} - onChangePage={(newPage) => setPage(newPage)} - onChangePerPage={handlePerPageChange} - /> - )} + {!isDetailsLoading && + (totalCount > 0 || + pendingChanges.secrets.length > 0 || + pendingChanges.folders.length > 0) && ( + s.type === PendingAction.Create).length + } + folderCount={ + totalFolderCount + + pendingChanges.folders.filter((f) => f.type === PendingAction.Create).length + } + secretRotationCount={totalSecretRotationCount} + /> + } + className="rounded-b-md border-t border-solid border-t-mineshaft-600" + count={totalCount + pendingChanges.secrets.length + pendingChanges.folders.length} + page={page} + perPage={perPage} + onChangePage={(newPage) => setPage(newPage)} + onChangePerPage={handlePerPageChange} + /> + )} togglePopUp(PopUpNames.CreateSecretForm, state)} @@ -772,6 +981,7 @@ const Page = () => { secretPath={secretPath} autoCapitalize={currentWorkspace?.autoCapitalization} isProtectedBranch={isProtectedBranch} + isBatchMode={isBatchMode} /> diff --git a/frontend/src/pages/secret-manager/SecretDashboardPage/SecretMainPage.store.tsx b/frontend/src/pages/secret-manager/SecretDashboardPage/SecretMainPage.store.tsx index 0e4ecca95..15ee3b9c6 100644 --- a/frontend/src/pages/secret-manager/SecretDashboardPage/SecretMainPage.store.tsx +++ b/frontend/src/pages/secret-manager/SecretDashboardPage/SecretMainPage.store.tsx @@ -1,13 +1,218 @@ +/* eslint-disable no-nested-ternary */ import { createContext, ReactNode, useContext, useEffect, useRef } from "react"; import { useRouter } from "@tanstack/react-router"; import { createStore, StateCreator, StoreApi, useStore } from "zustand"; import { useShallow } from "zustand/react/shallow"; +import { createNotification } from "@app/components/notifications"; +import { PendingAction } from "@app/hooks/api/secretFolders/types"; import { SecretV3RawSanitized } from "@app/hooks/api/secrets/types"; // akhilmhdh: Don't remove this file if ur thinking why use zustand just for selected selects state // This is first step and the whole secret crud will be moved to this global page scope state // this will allow more stuff like undo grouping stuffs etc + +// Base interface for all pending changes +export interface BasePendingChange { + id: string; + timestamp: number; +} + +// Secret-related change types +export interface PendingSecretCreate extends BasePendingChange { + resourceType: "secret"; + type: PendingAction.Create; + secretKey: string; + secretValue: string; + secretComment?: string; + skipMultilineEncoding?: boolean; + tags?: { id: string; slug: string }[]; + secretMetadata?: { key: string; value: string }[]; + originalKey?: string; +} + +export interface PendingSecretUpdate extends BasePendingChange { + resourceType: "secret"; + type: PendingAction.Update; + secretKey: string; + newSecretName?: string; + originalValue?: string; + secretValue?: string; + originalComment?: string; + secretComment?: string; + originalSkipMultilineEncoding?: boolean; + skipMultilineEncoding?: boolean; + originalTags?: { id: string; slug: string }[]; + tags?: { id: string; slug: string }[]; + originalSecretMetadata?: { key: string; value: string }[]; + secretMetadata?: { key: string; value: string }[]; + existingSecret: SecretV3RawSanitized; +} + +export interface PendingSecretDelete extends BasePendingChange { + resourceType: "secret"; + type: PendingAction.Delete; + secretKey: string; + secretValue: string; +} + +// Folder-related change types +export interface PendingFolderCreate extends BasePendingChange { + resourceType: "folder"; + type: PendingAction.Create; + id: string; + folderName: string; + description?: string; + parentPath: string; +} + +export interface PendingFolderUpdate extends BasePendingChange { + resourceType: "folder"; + type: PendingAction.Update; + originalFolderName: string; + folderName: string; + id: string; + originalDescription?: string; + description?: string; +} + +export interface PendingFolderDelete extends BasePendingChange { + resourceType: "folder"; + type: PendingAction.Delete; + id: string; + folderName: string; + folderPath: string; +} + +// Union types for each resource +export type PendingSecretChange = PendingSecretCreate | PendingSecretUpdate | PendingSecretDelete; +export type PendingFolderChange = PendingFolderCreate | PendingFolderUpdate | PendingFolderDelete; +export type PendingChange = PendingSecretChange | PendingFolderChange; + +// Grouped changes for better processing +export interface PendingChanges { + secrets: PendingSecretChange[]; + folders: PendingFolderChange[]; +} + +// Context interface for batch operations +export interface BatchContext { + workspaceId: string; + environment: string; + secretPath: string; +} + +const normalizeValue = (value: any): string | boolean | undefined => { + if (value === null || value === undefined || value === "") { + return undefined; + } + return value; +}; + +const areValuesEqual = (value1: any, value2: any): boolean => { + const normalized1 = normalizeValue(value1); + const normalized2 = normalizeValue(value2); + + if (normalized1 === undefined && normalized2 === undefined) { + return true; + } + + return normalized1 === normalized2; +}; + +const areArraysEqual = (arr1: any[] | undefined, arr2: any[] | undefined): boolean => { + // Handle undefined/null arrays + if (!arr1 && !arr2) return true; + if (!arr1 || !arr2) return false; + + // Compare lengths + if (arr1.length !== arr2.length) return false; + + // Deep comparison using JSON stringify (for simple objects) + return JSON.stringify(arr1.sort()) === JSON.stringify(arr2.sort()); +}; + +const cleanupRevertedSecretFields = (update: PendingSecretUpdate): PendingSecretUpdate | null => { + const cleaned = { ...update }; + let hasChanges = false; + + if ( + cleaned.secretValue !== undefined && + !areValuesEqual(cleaned.secretValue, cleaned.originalValue) + ) { + hasChanges = true; + } else { + cleaned.secretValue = undefined; + } + + if ( + cleaned.secretComment !== undefined && + (!areValuesEqual(cleaned.secretComment, cleaned.originalComment) || + !areValuesEqual(cleaned.secretComment, cleaned.existingSecret.comment)) + ) { + hasChanges = true; + } else { + cleaned.secretComment = undefined; + } + + if ( + cleaned.skipMultilineEncoding !== undefined && + cleaned.skipMultilineEncoding !== cleaned.originalSkipMultilineEncoding + ) { + hasChanges = true; + } else { + cleaned.skipMultilineEncoding = undefined; + } + + if (cleaned.tags !== undefined && !areArraysEqual(cleaned.tags, cleaned.originalTags)) { + hasChanges = true; + } else { + cleaned.tags = undefined; + } + + if ( + cleaned.secretMetadata !== undefined && + !areArraysEqual(cleaned.secretMetadata, cleaned.originalSecretMetadata) + ) { + hasChanges = true; + } else { + cleaned.secretMetadata = undefined; + } + + if (cleaned.newSecretName !== undefined && cleaned.newSecretName !== cleaned.secretKey) { + hasChanges = true; + } else { + cleaned.newSecretName = undefined; + } + + // If no changes remain, return null to indicate this update should be removed + return hasChanges ? cleaned : null; +}; + +const cleanupRevertedFolderFields = (update: PendingFolderUpdate): PendingFolderUpdate | null => { + const cleaned = { ...update }; + let hasChanges = false; + + if ( + cleaned.folderName !== undefined && + !areValuesEqual(cleaned.folderName, cleaned.originalFolderName) + ) { + hasChanges = true; + } + + if ( + cleaned.description !== undefined && + !areValuesEqual(cleaned.description, cleaned.originalDescription) + ) { + hasChanges = true; + } else { + cleaned.description = undefined; + } + + // If no changes remain, return null to indicate this update should be removed + return hasChanges ? cleaned : null; +}; + type SelectedSecretState = { selectedSecret: Record; action: { @@ -16,14 +221,16 @@ type SelectedSecretState = { set: (secrets: Record) => void; }; }; -const createSelectedSecretStore: StateCreator = (set) => ({ + +const createSelectedSecretStore: StateCreator = ( + set +) => ({ selectedSecret: {}, action: { toggle: (secret) => set((state) => { const isChecked = Boolean(state.selectedSecret?.[secret.id]); const newChecks = { ...state.selectedSecret }; - // remove selection if its present else add it if (isChecked) delete newChecks[secret.id]; else newChecks[secret.id] = secret; return { selectedSecret: newChecks }; @@ -33,6 +240,432 @@ const createSelectedSecretStore: StateCreator = (set) => ({ } }); +type BatchModeState = { + isBatchMode: boolean; + pendingChanges: PendingChanges; + pendingChangesByContext: Map; + existingSecretKeys: Set; + existingFolderNames: Set; + currentContext: BatchContext | null; + batchActions: { + addPendingChange: (change: PendingChange, context: BatchContext) => void; + loadPendingChanges: (context: BatchContext) => void; + clearAllPendingChanges: (context: BatchContext) => void; + setExistingKeys: (secretKeys: string[], folderNames: string[]) => void; + getTotalPendingChangesCount: () => number; + removePendingChange: (changeId: string, resourceType: string, context: BatchContext) => void; + }; +}; + +const generateContextKey = (workspaceId: string, environment: string, secretPath: string) => { + return `${workspaceId}_${environment}_${secretPath}`; +}; + +const createBatchModeStore: StateCreator = (set, get) => ({ + isBatchMode: true, // Always enabled by default + pendingChanges: { secrets: [], folders: [] }, + pendingChangesByContext: new Map(), + currentContext: null, + existingSecretKeys: new Set(), + existingFolderNames: new Set(), + batchActions: { + addPendingChange: (change: PendingChange, context: BatchContext) => + set((state) => { + const contextKey = generateContextKey( + context.workspaceId, + context.environment, + context.secretPath + ); + + // Get existing changes for this context or create new empty state + const existingChanges = state.pendingChangesByContext.get(contextKey) || { + secrets: [], + folders: [] + }; + const newChanges = { ...existingChanges }; + + if (change.resourceType === "folder") { + const existingFolder = + state.existingFolderNames.has(change.folderName) || + newChanges.folders.some((f) => f.folderName === change.folderName); + + if (change.type === PendingAction.Create && existingFolder) { + createNotification({ + text: "A folder with this name already exists", + type: "error" + }); + return { pendingChanges: newChanges }; + } + if ( + change.type === PendingAction.Update && + change.folderName !== change.originalFolderName && + existingFolder + ) { + createNotification({ + text: "A folder with this name already exists", + type: "error" + }); + return { pendingChanges: newChanges }; + } + } + + if (change.resourceType === "secret") { + const existingSecret = + state.existingSecretKeys.has(change.secretKey) || + newChanges.secrets.some( + (s) => + (s.secretKey === change.secretKey && s.type !== PendingAction.Create) || + (change.type === PendingAction.Create && + change.originalKey !== change.secretKey && + s.secretKey === change.secretKey) + ); + + if (change.type === PendingAction.Create && existingSecret) { + createNotification({ + text: "A secret with this name already exists", + type: "error" + }); + return { pendingChanges: newChanges }; + } + + const existingNewSecretName = + change.type === PendingAction.Update && + change.newSecretName && + change.newSecretName !== change.secretKey && + (state.existingSecretKeys.has(change.newSecretName) || + newChanges.secrets.some( + (s) => + (s.secretKey === change.newSecretName || + (s.type === PendingAction.Update && + s.newSecretName === change.newSecretName)) && + s.id !== change.id + )); + + if (existingNewSecretName) { + createNotification({ + text: "A secret with this name already exists", + type: "error" + }); + return { pendingChanges: newChanges }; + } + } + + if (change.resourceType === "secret") { + const secretChanges = [...newChanges.secrets]; + + if (change.type === PendingAction.Create) { + const existingCreateIndex = secretChanges.findIndex( + (c) => + c.type === PendingAction.Create && + (c.secretKey === change.secretKey || c.secretKey === change.originalKey) + ); + + if (existingCreateIndex >= 0) { + secretChanges[existingCreateIndex] = { + ...secretChanges[existingCreateIndex], + ...change, + timestamp: Date.now() + }; + } else { + secretChanges.push(change); + } + } else if (change.type === PendingAction.Update) { + const existingCreateIndex = secretChanges.findIndex( + (c) => c.type === PendingAction.Create && c.id === change.id + ); + + if (existingCreateIndex >= 0) { + const existingCreate = secretChanges[existingCreateIndex] as PendingSecretCreate; + secretChanges[existingCreateIndex] = { + ...existingCreate, + secretKey: change.newSecretName || change.secretKey || existingCreate.secretKey, + secretValue: + change.secretValue !== undefined + ? change.secretValue + : existingCreate.secretValue, + secretComment: + change.secretComment !== undefined + ? change.secretComment + : existingCreate.secretComment, + skipMultilineEncoding: + change.skipMultilineEncoding !== undefined + ? change.skipMultilineEncoding + : existingCreate.skipMultilineEncoding, + tags: change.tags !== undefined ? change.tags : existingCreate.tags, + secretMetadata: + change.secretMetadata !== undefined + ? change.secretMetadata + : existingCreate.secretMetadata, + timestamp: Date.now() + }; + } else { + const existingUpdateIndex = secretChanges.findIndex( + (c) => c.type === PendingAction.Update && c.id === change.id + ); + + if (existingUpdateIndex >= 0) { + const existingUpdate = secretChanges[existingUpdateIndex] as PendingSecretUpdate; + const mergedUpdate: PendingSecretUpdate = { + ...existingUpdate, + secretKey: existingUpdate.secretKey, + originalValue: existingUpdate.originalValue, + originalComment: existingUpdate.originalComment, + originalSkipMultilineEncoding: existingUpdate.originalSkipMultilineEncoding, + originalTags: existingUpdate.originalTags, + originalSecretMetadata: existingUpdate.originalSecretMetadata, + + newSecretName: + change.newSecretName !== undefined + ? change.newSecretName + : existingUpdate.newSecretName, + secretValue: + change.secretValue !== undefined + ? change.secretValue + : existingUpdate.secretValue, + secretComment: + change.secretComment !== undefined + ? change.secretComment + : existingUpdate.secretComment, + skipMultilineEncoding: + change.skipMultilineEncoding !== undefined + ? change.skipMultilineEncoding + : existingUpdate.skipMultilineEncoding, + tags: change.tags !== undefined ? change.tags : existingUpdate.tags, + secretMetadata: + change.secretMetadata !== undefined + ? change.secretMetadata + : existingUpdate.secretMetadata, + existingSecret: existingUpdate.existingSecret, + timestamp: Date.now() + }; + + // Clean up reverted fields and check if any changes remain + const cleanedUpdate = cleanupRevertedSecretFields(mergedUpdate); + + if (cleanedUpdate) { + // Still has changes, keep the update + secretChanges[existingUpdateIndex] = cleanedUpdate; + } else { + // No changes remain, remove the pending update + secretChanges.splice(existingUpdateIndex, 1); + } + } else { + // New update - clean it up before adding + const cleanedUpdate = cleanupRevertedSecretFields(change); + if (cleanedUpdate) { + secretChanges.push(cleanedUpdate); + } + // If cleanedUpdate is null, don't add it (no actual changes) + } + } + } else { + secretChanges.push(change); + } + + newChanges.secrets = secretChanges; + } else if (change.resourceType === "folder") { + const folderChanges = [...newChanges.folders]; + + if (change.type === PendingAction.Create) { + const existingCreateIndex = folderChanges.findIndex( + (c) => c.type === PendingAction.Create && c.folderName === change.folderName + ); + + if (existingCreateIndex >= 0) { + folderChanges[existingCreateIndex] = { + ...folderChanges[existingCreateIndex], + ...change, + timestamp: Date.now() + }; + } else { + folderChanges.push(change); + } + } else if (change.type === PendingAction.Update) { + const existingCreateIndex = folderChanges.findIndex( + (c) => c.type === PendingAction.Create && c.folderName === change.originalFolderName + ); + + if (existingCreateIndex >= 0) { + const existingCreate = folderChanges[existingCreateIndex] as PendingFolderCreate; + folderChanges[existingCreateIndex] = { + ...existingCreate, + folderName: change.folderName || existingCreate.folderName, + description: + change.description !== undefined + ? change.description + : existingCreate.description, + timestamp: Date.now() + }; + } else { + const existingUpdateIndex = folderChanges.findIndex( + (c) => c.type === PendingAction.Update && c.id === change.id + ); + + if (existingUpdateIndex >= 0) { + const existingUpdate = folderChanges[existingUpdateIndex] as PendingFolderUpdate; + + const mergedUpdate: PendingFolderUpdate = { + ...existingUpdate, + originalFolderName: existingUpdate.originalFolderName, + originalDescription: existingUpdate.originalDescription, + + folderName: + change.folderName !== undefined ? change.folderName : existingUpdate.folderName, + description: + change.description !== undefined + ? change.description + : existingUpdate.description, + + timestamp: Date.now() + }; + + // Clean up reverted fields and check if any changes remain + const cleanedUpdate = cleanupRevertedFolderFields(mergedUpdate); + + if (cleanedUpdate) { + // Still has changes, keep the update + folderChanges[existingUpdateIndex] = cleanedUpdate; + } else { + // No changes remain, remove the pending update + folderChanges.splice(existingUpdateIndex, 1); + } + } else { + // New update - clean it up before adding + const cleanedUpdate = cleanupRevertedFolderFields(change); + if (cleanedUpdate) { + folderChanges.push(cleanedUpdate); + } + // If cleanedUpdate is null, don't add it (no actual changes) + } + } + } else { + folderChanges.push(change); + } + + newChanges.folders = folderChanges; + } + + const updatedContextMap = new Map(state.pendingChangesByContext); + updatedContextMap.set(contextKey, newChanges); + + const currentChanges = + contextKey === + generateContextKey( + state.currentContext?.workspaceId || context.workspaceId, + state.currentContext?.environment || context.environment, + state.currentContext?.secretPath || context.secretPath + ) + ? newChanges + : state.pendingChanges; + + return { + pendingChangesByContext: updatedContextMap, + pendingChanges: currentChanges, + currentContext: context + }; + }), + + removePendingChange: (changeId: string, resourceType: string, context: BatchContext) => + set((state) => { + const contextKey = generateContextKey( + context.workspaceId, + context.environment, + context.secretPath + ); + + // Get existing changes for this context + const existingChanges = state.pendingChangesByContext.get(contextKey) || { + secrets: [], + folders: [] + }; + const newChanges = { ...existingChanges }; + + if (resourceType === "secret") { + newChanges.secrets = newChanges.secrets.filter((c) => c.id !== changeId); + } else if (resourceType === "folder") { + newChanges.folders = newChanges.folders.filter((c) => c.id !== changeId); + } + + const updatedContextMap = new Map(state.pendingChangesByContext); + updatedContextMap.set(contextKey, newChanges); + + const isCurrentContext = + state.currentContext && + contextKey === + generateContextKey( + state.currentContext.workspaceId, + state.currentContext.environment, + state.currentContext.secretPath + ); + + return { + pendingChangesByContext: updatedContextMap, + pendingChanges: isCurrentContext ? newChanges : state.pendingChanges + }; + }), + + loadPendingChanges: (context) => { + const contextKey = generateContextKey( + context.workspaceId, + context.environment, + context.secretPath + ); + + set((state) => { + const contextChanges = state.pendingChangesByContext.get(contextKey) || { + secrets: [], + folders: [] + }; + + return { + pendingChanges: contextChanges, + currentContext: context + }; + }); + }, + + clearAllPendingChanges: (context) => { + const contextKey = generateContextKey( + context.workspaceId, + context.environment, + context.secretPath + ); + + set((state) => { + // Clear changes for this specific context + const updatedContextMap = new Map(state.pendingChangesByContext); + updatedContextMap.delete(contextKey); + + // If this is the current context, also clear the active pending changes + const isCurrentContext = + state.currentContext && + contextKey === + generateContextKey( + state.currentContext.workspaceId, + state.currentContext.environment, + state.currentContext.secretPath + ); + + return { + pendingChangesByContext: updatedContextMap, + pendingChanges: isCurrentContext ? { secrets: [], folders: [] } : state.pendingChanges + }; + }); + }, + + setExistingKeys: (secretKeys, folderNames) => + set({ + existingSecretKeys: new Set(secretKeys), + existingFolderNames: new Set(folderNames) + }), + + getTotalPendingChangesCount: () => { + const state = get(); + return state.pendingChanges.secrets.length + state.pendingChanges.folders.length; + } + } +}); + export enum PopUpNames { CreateSecretForm = "create-secret-form" } @@ -58,13 +691,14 @@ const createPopUpStore: StateCreator = (set) => ({ } }); -type CombinedState = SelectedSecretState & PopUpState; +type CombinedState = SelectedSecretState & PopUpState & BatchModeState; const StoreContext = createContext | null>(null); export const StoreProvider = ({ children }: { children: ReactNode }) => { const storeRef = useRef>( createStore((...a) => ({ ...createSelectedSecretStore(...a), - ...createPopUpStore(...a) + ...createPopUpStore(...a), + ...createBatchModeStore(...a) })) ); const router = useRouter(); @@ -99,3 +733,17 @@ export const useSelectedSecretActions = () => useStoreContext(useShallow((state) export const usePopUpState = (id: PopUpNames) => useStoreContext(useShallow((state) => state.popUp?.[id] || { isOpen: false })); export const usePopUpAction = () => useStoreContext(useShallow((state) => state.popUpActions)); + +export const useBatchMode = () => + useStoreContext( + useShallow((state) => ({ + isBatchMode: state.isBatchMode, + pendingChanges: state.pendingChanges, + currentContext: state.currentContext, + totalChangesCount: state.batchActions.getTotalPendingChangesCount(), + secretChangesCount: state.pendingChanges.secrets.length, + folderChangesCount: state.pendingChanges.folders.length + })) + ); + +export const useBatchModeActions = () => useStoreContext(useShallow((state) => state.batchActions)); diff --git a/frontend/src/pages/secret-manager/SecretDashboardPage/components/ActionBar/ActionBar.tsx b/frontend/src/pages/secret-manager/SecretDashboardPage/components/ActionBar/ActionBar.tsx index e2680dbde..ea82cefb0 100644 --- a/frontend/src/pages/secret-manager/SecretDashboardPage/components/ActionBar/ActionBar.tsx +++ b/frontend/src/pages/secret-manager/SecretDashboardPage/components/ActionBar/ActionBar.tsx @@ -77,12 +77,15 @@ import { } from "@app/hooks/api/dashboard/queries"; import { UsedBySecretSyncs } from "@app/hooks/api/dashboard/types"; import { secretApprovalRequestKeys } from "@app/hooks/api/secretApprovalRequest/queries"; +import { PendingAction } from "@app/hooks/api/secretFolders/types"; import { fetchProjectSecrets, secretKeys } from "@app/hooks/api/secrets/queries"; import { ApiErrorTypes, SecretType, TApiErrors, WsTag } from "@app/hooks/api/types"; import { SecretSearchInput } from "@app/pages/secret-manager/OverviewPage/components/SecretSearchInput"; import { + PendingFolderCreate, PopUpNames, + useBatchModeActions, usePopUpAction, useSelectedSecretActions, useSelectedSecrets @@ -112,6 +115,7 @@ type Props = { filter: Filter; tags?: WsTag[]; isVisible?: boolean; + isBatchMode?: boolean; snapshotCount: number; isSnapshotCountLoading?: boolean; protectedBranchPolicyName?: string; @@ -142,6 +146,7 @@ export const ActionBar = ({ filter, tags = [], isVisible, + isBatchMode, snapshotCount, isSnapshotCountLoading, onSearchChange, @@ -182,6 +187,7 @@ export const ActionBar = ({ options: { onSuccess: undefined } }); const queryClient = useQueryClient(); + const { addPendingChange } = useBatchModeActions(); const selectedSecrets = useSelectedSecrets(); const { reset: resetSelectedSecret } = useSelectedSecretActions(); @@ -192,6 +198,28 @@ export const ActionBar = ({ const handleFolderCreate = async (folderName: string, description: string | null) => { try { + if (isBatchMode) { + const folderId = `${folderName}`; + const pendingFolderCreate: PendingFolderCreate = { + id: folderId, + resourceType: "folder", + type: PendingAction.Create, + folderName, + description: description || undefined, + parentPath: secretPath, + timestamp: Date.now() + }; + + addPendingChange(pendingFolderCreate, { + workspaceId, + environment, + secretPath + }); + + handlePopUpClose("addFolder"); + return; + } + await createFolder({ name: folderName, path: secretPath, diff --git a/frontend/src/pages/secret-manager/SecretDashboardPage/components/ActionBar/FolderForm.tsx b/frontend/src/pages/secret-manager/SecretDashboardPage/components/ActionBar/FolderForm.tsx index 885838498..ab3a71af5 100644 --- a/frontend/src/pages/secret-manager/SecretDashboardPage/components/ActionBar/FolderForm.tsx +++ b/frontend/src/pages/secret-manager/SecretDashboardPage/components/ActionBar/FolderForm.tsx @@ -8,7 +8,12 @@ import { TextArea } from "@app/components/v2/TextArea/TextArea"; type Props = { onCreateFolder?: (folderName: string, description: string | null) => Promise; - onUpdateFolder?: (folderName: string, description: string | null) => Promise; + onUpdateFolder?: ( + folderName: string, + description: string | null, + oldFolderName?: string, + oldFolderDescription?: string + ) => Promise; isEdit?: boolean; defaultFolderName?: string; defaultDescription?: string; @@ -69,7 +74,7 @@ export const FolderForm = ({ const descriptionShaped = description && description.trim() !== "" ? description : null; if (isEdit) { - await onUpdateFolder?.(name, descriptionShaped); + await onUpdateFolder?.(name, descriptionShaped, defaultFolderName, defaultDescription); } else { await onCreateFolder?.(name, descriptionShaped); } diff --git a/frontend/src/pages/secret-manager/SecretDashboardPage/components/CommitForm/CommitForm.tsx b/frontend/src/pages/secret-manager/SecretDashboardPage/components/CommitForm/CommitForm.tsx new file mode 100644 index 000000000..c2e3ab12b --- /dev/null +++ b/frontend/src/pages/secret-manager/SecretDashboardPage/components/CommitForm/CommitForm.tsx @@ -0,0 +1,446 @@ +/* eslint-disable jsx-a11y/label-has-associated-control */ +import React, { useCallback, useState } from "react"; +import { faCodeCommit, faEye, faFolder, faKey } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; + +import { Badge, Button, Input, Modal, ModalContent } from "@app/components/v2"; +import { PendingAction } from "@app/hooks/api/secretFolders/types"; +import { SecretVersionDiffView } from "@app/pages/secret-manager/CommitDetailsPage/components/SecretVersionDiffView"; + +import { + PendingChange, + PendingChanges, + useBatchMode, + useBatchModeActions +} from "../../SecretMainPage.store"; + +interface CommitFormProps { + onCommit: (changes: PendingChanges, commitMessage: string) => Promise; + isCommitting?: boolean; + environment: string; + workspaceId: string; + secretPath: string; +} + +interface ResourceChangeProps { + change: PendingChange; + environment: string; + workspaceId: string; + secretPath: string; +} + +type RenderResourceProps = { + onDiscard: () => void; + change: PendingChange; +}; + +const RenderSecretChanges = ({ onDiscard, change }: RenderResourceProps) => { + if (change.resourceType !== "secret") return null; + + if (change.type === PendingAction.Create) { + return ( + + ); + } + + if (change.type === PendingAction.Update) { + const { existingSecret } = change; + + const hasKeyChange = change.newSecretName && change.secretKey !== change.newSecretName; + const hasValueChange = change.secretValue !== change.originalValue; + const hasCommentChange = change.secretComment !== change.originalComment; + const hasMultilineChange = + change.skipMultilineEncoding !== change.originalSkipMultilineEncoding; + const hasTagsChange = JSON.stringify(change.tags) !== JSON.stringify(change.originalTags); + const hasMetadataChange = + JSON.stringify(change.secretMetadata) !== JSON.stringify(change.originalSecretMetadata); + + const hasChanges = [ + hasKeyChange, + hasValueChange, + hasCommentChange, + hasMultilineChange, + hasTagsChange, + hasMetadataChange + ].some(Boolean); + + if (!hasChanges) return null; + + return ( + tag.slug) ?? []) : undefined, + secretMetadata: change.secretMetadata ? existingSecret.secretMetadata : undefined, + skipMultilineEncoding: + typeof change.skipMultilineEncoding === "boolean" + ? existingSecret.skipMultilineEncoding + : undefined, + comment: change.secretComment !== undefined ? existingSecret.comment : undefined + }, + { + version: 2, // placeholder, not used + secretKey: change.newSecretName, + secretValue: change.secretValue, + tags: change.tags?.map((tag) => tag.slug), + secretMetadata: change.secretMetadata, + skipMultilineEncoding: change.skipMultilineEncoding, + comment: change.secretComment + } + ] + }} + /> + ); + } + + if (change.type === PendingAction.Delete) { + const { secretKey, secretValue } = change; + return ( + + ); + } + + return null; +}; + +const RenderFolderChanges = ({ onDiscard, change }: RenderResourceProps) => { + if (change.resourceType !== "folder") return null; + + if (change.type === PendingAction.Create) { + return ( + + ); + } + + if (change.type === PendingAction.Update) { + const hasNameChange = change.folderName !== change.originalFolderName; + const hasDescriptionChange = change.description !== change.originalDescription; + + const hasChanges = [hasNameChange, hasDescriptionChange].some(Boolean); + + if (!hasChanges) return null; + + return ( + + ); + } + + if (change.type === PendingAction.Delete) { + return ( + + ); + } + + return null; +}; + +const ResourceChange: React.FC = ({ + change, + environment, + workspaceId, + secretPath +}) => { + const { removePendingChange } = useBatchModeActions(); + + const handleDeletePending = useCallback( + (changeType: string, id: string) => { + removePendingChange(id, changeType, { + workspaceId, + environment, + secretPath + }); + }, + [change.resourceType, change.id] + ); + + return change.resourceType === "secret" ? ( + handleDeletePending(change.resourceType, change.id)} + /> + ) : ( + handleDeletePending(change.resourceType, change.id)} + /> + ); +}; + +export const CommitForm: React.FC = ({ + onCommit, + isCommitting = false, + environment, + workspaceId, + secretPath +}) => { + const { isBatchMode, pendingChanges, totalChangesCount } = useBatchMode(); + + const [isModalOpen, setIsModalOpen] = useState(false); + const [commitMessage, setCommitMessage] = useState(""); + const { clearAllPendingChanges } = useBatchModeActions(); + + if (!isBatchMode || totalChangesCount === 0) { + return null; + } + + const handleCommit = async () => { + if (!commitMessage.trim()) { + return; + } + await onCommit(pendingChanges, commitMessage); + clearAllPendingChanges({ + workspaceId, + environment, + secretPath + }); + setIsModalOpen(false); + setCommitMessage(""); + }; + + return ( + <> + {/* Floating Panel */} + {!isModalOpen && ( + + + {/* Left Content */} + + {/* Header */} + + + Pending Changes + + {totalChangesCount} Change{totalChangesCount !== 1 ? "s" : ""} + + + + {/* Description */} + + Review pending changes and commit them to apply the updates. + + + + {/* Right Buttons */} + + clearAllPendingChanges({ workspaceId, environment, secretPath })} + isDisabled={totalChangesCount === 0} + variant="outline_bg" + className="px-4 hover:border-red/40 hover:bg-red/[0.1]" + > + Discard + + } + onClick={() => setIsModalOpen(true)} + isDisabled={totalChangesCount === 0} + className="px-6" + > + Review Changes + + + + + )} + + {/* Commit Modal */} + + + + Commit Changes + + {totalChangesCount} Change{totalChangesCount !== 1 ? "s" : ""} + + + } + subTitle={"Write a commit message and review the changes you're about to commit."} + className="max-h-[90vh] max-w-[95%] md:max-w-7xl" + > + + {/* Changes List */} + + + {/* Folder Changes */} + {pendingChanges.folders.length > 0 && ( + + + + Folders ({pendingChanges.folders.length}) + + + {pendingChanges.folders.map((change) => ( + + ))} + + + )} + + {/* Secret Changes */} + {pendingChanges.secrets.length > 0 && ( + + + + Secrets ({pendingChanges.secrets.length}) + + + {pendingChanges.secrets.map((change) => ( + + ))} + + + )} + + + + {/* Commit Message */} + + + Commit Message * + + setCommitMessage(e.target.value)} + placeholder="Describe your changes..." + className="w-full" + required + /> + + + {/* Action Buttons */} + + setIsModalOpen(false)} + isDisabled={isCommitting} + > + Cancel + + } + colorSchema="primary" + variant="outline_bg" + > + {isCommitting ? "Committing..." : "Commit Changes"} + + + + + + > + ); +}; diff --git a/frontend/src/pages/secret-manager/SecretDashboardPage/components/CommitForm/index.tsx b/frontend/src/pages/secret-manager/SecretDashboardPage/components/CommitForm/index.tsx new file mode 100644 index 000000000..47502d9a5 --- /dev/null +++ b/frontend/src/pages/secret-manager/SecretDashboardPage/components/CommitForm/index.tsx @@ -0,0 +1 @@ +export { CommitForm } from "./CommitForm"; diff --git a/frontend/src/pages/secret-manager/SecretDashboardPage/components/CreateSecretForm/CreateSecretForm.tsx b/frontend/src/pages/secret-manager/SecretDashboardPage/components/CreateSecretForm/CreateSecretForm.tsx index a4318d53a..9b43d820d 100644 --- a/frontend/src/pages/secret-manager/SecretDashboardPage/components/CreateSecretForm/CreateSecretForm.tsx +++ b/frontend/src/pages/secret-manager/SecretDashboardPage/components/CreateSecretForm/CreateSecretForm.tsx @@ -12,9 +12,15 @@ import { InfisicalSecretInput } from "@app/components/v2/InfisicalSecretInput"; import { ProjectPermissionActions, ProjectPermissionSub, useProjectPermission } from "@app/context"; import { getKeyValue } from "@app/helpers/parseEnvVar"; import { useCreateSecretV3, useCreateWsTag, useGetWsTags } from "@app/hooks/api"; +import { PendingAction } from "@app/hooks/api/secretFolders/types"; import { SecretType } from "@app/hooks/api/types"; -import { PopUpNames, usePopUpAction } from "../../SecretMainPage.store"; +import { + PendingSecretCreate, + PopUpNames, + useBatchModeActions, + usePopUpAction +} from "../../SecretMainPage.store"; const typeSchema = z.object({ key: z.string().trim().min(1, { message: "Secret key is required" }), @@ -31,6 +37,7 @@ type Props = { // modal props autoCapitalize?: boolean; isProtectedBranch?: boolean; + isBatchMode?: boolean; }; export const CreateSecretForm = ({ @@ -38,7 +45,8 @@ export const CreateSecretForm = ({ workspaceId, secretPath = "/", autoCapitalize = true, - isProtectedBranch = false + isProtectedBranch = false, + isBatchMode = false }: Props) => { const { register, @@ -53,6 +61,7 @@ export const CreateSecretForm = ({ const { mutateAsync: createSecretV3 } = useCreateSecretV3(); const createWsTag = useCreateWsTag(); + const { addPendingChange } = useBatchModeActions(); const { permission } = useProjectPermission(); const canReadTags = permission.can(ProjectPermissionActions.Read, ProjectPermissionSub.Tags); @@ -85,6 +94,26 @@ export const CreateSecretForm = ({ const handleFormSubmit = async ({ key, value, tags }: TFormSchema) => { try { + if (isBatchMode) { + const pendingSecretCreate: PendingSecretCreate = { + id: key, + type: PendingAction.Create, + secretKey: key, + secretValue: value || "", + secretComment: "", + tags: tags?.map((el) => ({ id: el.value, slug: el.label })), + timestamp: Date.now(), + resourceType: "secret" + }; + addPendingChange(pendingSecretCreate, { + workspaceId, + environment, + secretPath + }); + closePopUp(PopUpNames.CreateSecretForm); + reset(); + return; + } await createSecretV3({ environment, workspaceId, diff --git a/frontend/src/pages/secret-manager/SecretDashboardPage/components/DynamicSecretListView/DynamicSecretListView.tsx b/frontend/src/pages/secret-manager/SecretDashboardPage/components/DynamicSecretListView/DynamicSecretListView.tsx index d652d49ad..57ede8d0c 100644 --- a/frontend/src/pages/secret-manager/SecretDashboardPage/components/DynamicSecretListView/DynamicSecretListView.tsx +++ b/frontend/src/pages/secret-manager/SecretDashboardPage/components/DynamicSecretListView/DynamicSecretListView.tsx @@ -1,10 +1,5 @@ import { subject } from "@casl/ability"; -import { - faClose, - faFingerprint, - faPencilSquare, - faWarning -} from "@fortawesome/free-solid-svg-icons"; +import { faEdit, faFingerprint, faTrash, faWarning } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { createNotification } from "@app/components/notifications"; @@ -187,7 +182,7 @@ export const DynamicSecretListView = ({ )} - + - + )} @@ -228,6 +223,7 @@ export const DynamicSecretListView = ({ { @@ -236,7 +232,7 @@ export const DynamicSecretListView = ({ }} isDisabled={!isAllowed || isRevoking} > - + )} diff --git a/frontend/src/pages/secret-manager/SecretDashboardPage/components/FolderListView/FolderListView.tsx b/frontend/src/pages/secret-manager/SecretDashboardPage/components/FolderListView/FolderListView.tsx index b95e73fb8..e0cc3f78b 100644 --- a/frontend/src/pages/secret-manager/SecretDashboardPage/components/FolderListView/FolderListView.tsx +++ b/frontend/src/pages/secret-manager/SecretDashboardPage/components/FolderListView/FolderListView.tsx @@ -1,7 +1,15 @@ import { subject } from "@casl/ability"; -import { faClose, faFolder, faInfoCircle, faPencilSquare } from "@fortawesome/free-solid-svg-icons"; +import { + faClose, + faEdit, + faFolder, + faInfoCircle, + faPencilSquare, + faTrash +} from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { useNavigate, useSearch } from "@tanstack/react-router"; +import { twMerge } from "tailwind-merge"; import { createNotification } from "@app/components/notifications"; import { ProjectPermissionCan } from "@app/components/permissions"; @@ -11,8 +19,15 @@ import { ROUTE_PATHS } from "@app/const/routes"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context"; import { usePopUp } from "@app/hooks"; import { useDeleteFolder, useUpdateFolder } from "@app/hooks/api"; -import { TSecretFolder } from "@app/hooks/api/secretFolders/types"; +import { PendingAction, TSecretFolder } from "@app/hooks/api/secretFolders/types"; +import { + PendingFolderCreate, + PendingFolderDelete, + PendingFolderUpdate, + useBatchMode, + useBatchModeActions +} from "../../SecretMainPage.store"; import { FolderForm } from "../ActionBar/FolderForm"; type Props = { @@ -42,10 +57,62 @@ export const FolderListView = ({ const { mutateAsync: updateFolder } = useUpdateFolder(); const { mutateAsync: deleteFolder } = useDeleteFolder(); + const { isBatchMode } = useBatchMode(); + const { addPendingChange, removePendingChange } = useBatchModeActions(); - const handleFolderUpdate = async (newFolderName: string, newFolderDescription: string | null) => { + const handleFolderUpdate = async ( + newFolderName: string, + newFolderDescription: string | null, + oldFolderName?: string, + oldFolderDescription?: string + ) => { try { - const { id: folderId } = popUp.updateFolder.data as TSecretFolder; + const updateFolderData = popUp.updateFolder.data; + if (!updateFolderData) throw new Error("Update folder data is required"); + const { id: folderId, pendingAction, isPending } = updateFolderData as TSecretFolder; + + if (isBatchMode) { + const isEditingPendingCreation = isPending && pendingAction === PendingAction.Create; + + if (isEditingPendingCreation) { + const updatedCreate: PendingFolderCreate = { + id: folderId, + type: PendingAction.Create, + folderName: newFolderName, + description: newFolderDescription || undefined, + parentPath: secretPath, + timestamp: Date.now(), + resourceType: "folder" + }; + + addPendingChange(updatedCreate, { + workspaceId, + environment, + secretPath + }); + } else { + const updateChange: PendingFolderUpdate = { + id: folderId, + type: PendingAction.Update, + originalFolderName: oldFolderName || "", + folderName: newFolderName, + originalDescription: oldFolderDescription, + description: newFolderDescription || undefined, + timestamp: Date.now(), + resourceType: "folder" + }; + + addPendingChange(updateChange, { + workspaceId, + environment, + secretPath + }); + } + + handlePopUpClose("updateFolder"); + return; + } + await updateFolder({ folderId, name: newFolderName, @@ -68,15 +135,45 @@ export const FolderListView = ({ } }; + const handleDeletePending = (id: string) => { + removePendingChange(id, "folder", { + workspaceId, + environment, + secretPath + }); + }; + const handleFolderDelete = async () => { try { - const { id: folderId } = popUp.deleteFolder.data as TSecretFolder; + const folderData = popUp.deleteFolder?.data as TSecretFolder; + + if (isBatchMode) { + const pendingFolderDelete: PendingFolderDelete = { + id: folderData.id, + folderName: folderData.name, + folderPath: secretPath, + resourceType: "folder", + type: PendingAction.Delete, + timestamp: Date.now() + }; + + addPendingChange(pendingFolderDelete, { + workspaceId, + environment, + secretPath + }); + + handlePopUpClose("deleteFolder"); + return; + } + await deleteFolder({ - folderId, + folderId: folderData.id, path: secretPath, environment, projectId: workspaceId }); + handlePopUpClose("deleteFolder"); createNotification({ type: "success", @@ -91,7 +188,10 @@ export const FolderListView = ({ } }; - const handleFolderClick = (name: string) => { + const handleFolderClick = (name: string, isPending?: boolean) => { + if (isPending) { + return; + } const path = `${secretPathQueryparam === "/" ? "" : secretPathQueryparam}/${name}`; navigate({ search: (el) => ({ ...el, secretPath: path }) @@ -100,10 +200,16 @@ export const FolderListView = ({ return ( <> - {folders.map(({ name, id, description }) => ( + {folders.map(({ name, id, description, pendingAction, isPending }) => ( @@ -113,9 +219,9 @@ export const FolderListView = ({ role="button" tabIndex={0} onKeyDown={(evt) => { - if (evt.key === "Enter") handleFolderClick(name); + if (evt.key === "Enter") handleFolderClick(name, isPending); }} - onClick={() => handleFolderClick(name)} + onClick={() => handleFolderClick(name, isPending)} > {name} {description && ( @@ -128,46 +234,72 @@ export const FolderListView = ({ )} - - - {(isAllowed) => ( - handlePopUpOpen("updateFolder", { id, name, description })} - isDisabled={!isAllowed} - > - - - )} - - - {(isAllowed) => ( - handlePopUpOpen("deleteFolder", { id, name })} - isDisabled={!isAllowed} - > - - - )} - - + {isPending ? ( + + {}} + > + + + + handleDeletePending(id)} + > + + + + ) : ( + + + {(isAllowed) => ( + handlePopUpOpen("updateFolder", { id, name, description })} + isDisabled={!isAllowed} + > + + + )} + + + {(isAllowed) => ( + handlePopUpOpen("deleteFolder", { id, name })} + isDisabled={!isAllowed} + > + + + )} + + + )} ))} )} - + - + )} diff --git a/frontend/src/pages/secret-manager/SecretDashboardPage/components/SecretListView/SecretDetailSidebar.tsx b/frontend/src/pages/secret-manager/SecretDashboardPage/components/SecretListView/SecretDetailSidebar.tsx index 61dbdb4be..fbd4565aa 100644 --- a/frontend/src/pages/secret-manager/SecretDashboardPage/components/SecretListView/SecretDetailSidebar.tsx +++ b/frontend/src/pages/secret-manager/SecretDashboardPage/components/SecretListView/SecretDetailSidebar.tsx @@ -52,6 +52,7 @@ import { useWorkspace } from "@app/context"; import { ProjectPermissionSecretActions } from "@app/context/ProjectPermissionContext/types"; +import { getProjectBaseURL } from "@app/helpers/project"; import { usePopUp, useToggle } from "@app/hooks"; import { useGetSecretVersion } from "@app/hooks/api"; import { ActorType } from "@app/hooks/api/auditLogs/enums"; @@ -980,7 +981,9 @@ export const SecretDetailSidebar = ({ className="z-[100] capitalize" > - Save Changes + Apply Changes )} diff --git a/frontend/src/pages/secret-manager/SecretDashboardPage/components/SecretListView/SecretItem.tsx b/frontend/src/pages/secret-manager/SecretDashboardPage/components/SecretListView/SecretItem.tsx index bee8266f6..707284fcf 100644 --- a/frontend/src/pages/secret-manager/SecretDashboardPage/components/SecretListView/SecretItem.tsx +++ b/frontend/src/pages/secret-manager/SecretDashboardPage/components/SecretListView/SecretItem.tsx @@ -38,7 +38,7 @@ import { WsTag } from "@app/hooks/api/types"; import { subject } from "@casl/ability"; import { zodResolver } from "@hookform/resolvers/zod"; import { AnimatePresence, motion } from "framer-motion"; -import { memo, useEffect } from "react"; +import { memo, useCallback, useEffect, useRef } from "react"; import { Controller, useFieldArray, useForm } from "react-hook-form"; import { twMerge } from "tailwind-merge"; import { @@ -50,6 +50,7 @@ import { ProjectPermissionSecretActions } from "@app/context/ProjectPermissionCo import { hasSecretReadValueOrDescribePermission } from "@app/lib/fn/permission"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faEyeSlash, faKey, faRotate } from "@fortawesome/free-solid-svg-icons"; +import { PendingAction } from "@app/hooks/api/secretFolders/types"; import { FontAwesomeSpriteName, formSchema, @@ -57,6 +58,7 @@ import { TFormSchema } from "./SecretListView.utils"; import { CollapsibleSecretImports } from "./CollapsibleSecretImports"; +import { useBatchModeActions } from "../../SecretMainPage.store"; export const HIDDEN_SECRET_VALUE = "******"; export const HIDDEN_SECRET_VALUE_API_MASK = ""; @@ -86,6 +88,8 @@ type Props = { isImported: boolean; }[]; }[]; + isPending?: boolean; + pendingAction?: PendingAction; }; export const SecretItem = memo( @@ -102,7 +106,9 @@ export const SecretItem = memo( environment, secretPath, handleSecretShare, - importedBy + importedBy, + isPending, + pendingAction }: Props) => { const { handlePopUpOpen, handlePopUpToggle, handlePopUpClose, popUp } = usePopUp([ "editSecret" @@ -110,6 +116,18 @@ export const SecretItem = memo( const { currentWorkspace } = useWorkspace(); const { permission } = useProjectPermission(); const { isRotatedSecret } = secret; + const { removePendingChange } = useBatchModeActions(); + + const autoSaveTimeoutRef = useRef(); + const isAutoSavingRef = useRef(false); + + const handleDeletePending = (pendingSecret: SecretV3RawSanitized) => { + removePendingChange(pendingSecret.id, "secret", { + workspaceId: currentWorkspace.id, + environment, + secretPath + }); + }; const canEditSecretValue = permission.can( ProjectPermissionSecretActions.Edit, @@ -151,7 +169,6 @@ export const SecretItem = memo( }); const secretName = watch("key"); - const overrideAction = watch("overrideAction"); const hasComment = Boolean(watch("comment")); @@ -167,6 +184,56 @@ export const SecretItem = memo( name: "tags" }); + const isOverriden = + overrideAction === SecretActionType.Created || overrideAction === SecretActionType.Modified; + const hasTagsApplied = Boolean(fields.length); + + const autoSaveChanges = useCallback( + async (data: TFormSchema) => { + if (isAutoSavingRef.current) return; + if ( + data.overrideAction === SecretActionType.Created || + data.overrideAction === SecretActionType.Modified + ) { + return; + } + + isAutoSavingRef.current = true; + try { + await onSaveSecret(secret, { ...secret, ...data }, () => { + reset(); + }); + } catch (error) { + console.error("Auto-save failed:", error); + } finally { + isAutoSavingRef.current = false; + } + }, + [secret, onSaveSecret, importedBy, reset] + ); + + const formValues = watch(); + + useEffect(() => { + if (autoSaveTimeoutRef.current) { + clearTimeout(autoSaveTimeoutRef.current); + } + + if (isDirty && !isSubmitting && !isAutoSavingRef.current) { + const debounceTime = 600; + + autoSaveTimeoutRef.current = setTimeout(() => { + autoSaveChanges(formValues); + }, debounceTime); + } + + return () => { + if (autoSaveTimeoutRef.current) { + clearTimeout(autoSaveTimeoutRef.current); + } + }; + }, [formValues, isDirty, isSubmitting, autoSaveChanges, isPending]); + const isReadOnly = hasSecretReadValueOrDescribePermission( permission, @@ -188,6 +255,9 @@ export const SecretItem = memo( }) ); + const isReadOnlySecret = + isReadOnly || isRotatedSecret || (isPending && pendingAction === PendingAction.Delete); + const { secretValueHidden } = secret; const [isSecValueCopied, setIsSecValueCopied] = useToggle(false); @@ -199,10 +269,6 @@ export const SecretItem = memo( return () => clearTimeout(timer); }, [isSecValueCopied]); - const isOverriden = - overrideAction === SecretActionType.Created || overrideAction === SecretActionType.Modified; - const hasTagsApplied = Boolean(fields.length); - const handleOverrideClick = () => { if (isOverriden) { // override need not be flagged delete if it was never saved in server @@ -267,20 +333,27 @@ export const SecretItem = memo( setIsSecValueCopied.on(); }; + const isInAutoSaveMode = isDirty && !isSubmitting && !isOverriden; + return ( {secret.isRotatedSecret ? ( @@ -364,7 +437,7 @@ export const SecretItem = memo( control={control} render={({ field }) => ( )} - - - - - - - - {(isAllowed) => ( - - - - - - - - - e.preventDefault()} // prevents secret input from displaying value on open - > - - - - )} - - - - {(isAllowed) => ( - - - - - - - - )} - - - Add tags to this secret - {tags.map((tag) => { - const { id: tagId, slug, color } = tag; - - const isTagSelected = selectedTagsGroupById?.[tagId]; - return ( - handleTagSelect(tag)} - key={`${secret.id}-${tagId}`} - icon={ - isTagSelected && ( - - ) - } - iconPos="right" - > - - - {slug} - - - ); - })} - - - } - onClick={onCreateTag} - > - Create a tag - - - - - - {(isAllowed) => ( + - - )} - - - - {(isAllowed) => ( - - - - - - - - )} - - - - - - - - - - - - - - - - {!isDirty ? ( - - - onDetailViewSecret(secret)} - > - + {(isAllowed) => ( + + + + + + + + + e.preventDefault()} + > + + + + )} + + + + {(isAllowed) => ( + + + + + + + + )} + + + Add tags to this secret + {tags.map((tag) => { + const { id: tagId, slug, color } = tag; + + const isTagSelected = selectedTagsGroupById?.[tagId]; + return ( + handleTagSelect(tag)} + key={`${secret.id}-${tagId}`} + icon={ + isTagSelected && ( + + ) + } + iconPos="right" + > + + + {slug} + + + ); + })} + + + } + onClick={onCreateTag} + > + Create a tag + + + + + {(isAllowed) => ( + + + + )} + + + + {(isAllowed) => ( + + + + + + + + )} + + + + + + + + + + + + + + )} + {pendingAction === PendingAction.Create && ( + + + + {(isAllowed) => ( + + + + + + + + )} + + + Add tags to this secret + {tags.map((tag) => { + const { id: tagId, slug, color } = tag; + + const isTagSelected = selectedTagsGroupById?.[tagId]; + return ( + handleTagSelect(tag)} + key={`${secret.id}-${tagId}`} + icon={ + isTagSelected && ( + + ) + } + iconPos="right" + > + + + {slug} + + + ); + })} + + + } + onClick={onCreateTag} + > + Create a tag + + + + + + )} + + + {isInAutoSaveMode ? ( + + + + ) : !isDirty ? ( + isPending ? ( + + + onDetailViewSecret(secret)} + isDisabled={pendingAction !== "update"} + > + + + + + onDeleteSecret(secret)} - isDisabled={!isAllowed || isRotatedSecret} + onClick={() => handleDeletePending(secret)} > - )} - - + + + ) : ( + + + onDetailViewSecret(secret)} + > + + + + + {(isAllowed) => ( + onDeleteSecret(secret)} + isDisabled={!isAllowed || isRotatedSecret} + > + + + )} + + + ) ) : ( 0 || pendingChanges.folders.length > 0, + message: + "You have unsaved changes. If you leave now, your work will be lost. Do you want to continue?", + context: { + workspaceId, + environment, + secretPath + } + }); + const { addPendingChange } = useBatchModeActions(); const handleSecretOperation = async ( operation: "create" | "update" | "delete", @@ -170,11 +188,56 @@ export const SecretListView = ({ ); }; + function getTrueOriginalSecret( + currentSecret: SecretV3RawSanitized, + pendingSecrets: PendingSecretChange[] + ): Omit & { + tags?: { id: string; slug: string }[]; + } { + // Find if there's already a pending change for this secret + const existingChange = pendingSecrets.find((change) => change.id === currentSecret.id); + + if (!existingChange || existingChange.type === "create") { + // If no existing change or it's a creation, current secret is the original + return { + ...currentSecret, + tags: currentSecret.tags?.map((tag) => ({ + id: tag.id, + slug: tag.slug + })) + }; + } + + if (existingChange.type === "update") { + // If there's an existing update, reconstruct the original from the stored original values + return { + ...currentSecret, + key: existingChange.secretKey, // Original key + value: existingChange.originalValue || currentSecret.value, + comment: existingChange.originalComment || currentSecret.comment, + skipMultilineEncoding: + existingChange.originalSkipMultilineEncoding ?? currentSecret.skipMultilineEncoding, + tags: + existingChange.originalTags?.map((tag) => ({ + id: tag.id, + slug: tag.slug + })) || currentSecret.tags, + secretMetadata: existingChange.originalSecretMetadata || currentSecret.secretMetadata + }; + } + + return { + ...currentSecret, + tags: currentSecret.tags?.map((tag) => ({ id: tag.id, slug: tag.slug })) + }; + } + + // Improved handleSaveSecret function const handleSaveSecret = useCallback( async ( orgSecret: SecretV3RawSanitized, modSecret: Omit & { - tags?: { id: string }[]; + tags?: { id: string; name?: string; slug?: string }[]; secretMetadata?: { key: string; value: string }[]; }, cb?: () => void @@ -192,7 +255,9 @@ export const SecretListView = ({ reminderNote, reminderRecipients, secretMetadata, - isReminderEvent + isReminderEvent, + isPending, + pendingAction } = modSecret; const hasKeyChanged = oldKey !== key && key; @@ -246,6 +311,80 @@ export const SecretListView = ({ // shared secret change if (!isSharedSecUnchanged && !personalAction) { + if (isBatchMode) { + const isEditingPendingCreation = isPending && pendingAction === PendingAction.Create; + + if (isEditingPendingCreation) { + const updatedCreate: PendingSecretCreate = { + id: orgSecret.id, + type: PendingAction.Create, + secretKey: key, + secretValue: value || "", + secretComment: comment || "", + skipMultilineEncoding: modSecret.skipMultilineEncoding || false, + tags: tags?.map((tag) => ({ id: tag.id, slug: tag.name || tag.slug || "" })) || [], + secretMetadata: secretMetadata || [], + timestamp: Date.now(), + resourceType: "secret", + originalKey: oldKey + }; + + addPendingChange(updatedCreate, { + workspaceId, + environment, + secretPath + }); + } else { + const trueOriginalSecret = getTrueOriginalSecret(orgSecret, pendingChanges.secrets); + + const updateChange: PendingSecretUpdate = { + id: orgSecret.id, + type: PendingAction.Update, + secretKey: trueOriginalSecret.key, + ...(key !== trueOriginalSecret.key && { newSecretName: key }), + ...(value !== trueOriginalSecret.value && { + originalValue: trueOriginalSecret.value, + secretValue: value + }), + ...(comment !== trueOriginalSecret.comment && { + originalComment: trueOriginalSecret.comment, + secretComment: comment + }), + ...(modSecret.skipMultilineEncoding !== + trueOriginalSecret.skipMultilineEncoding && { + originalSkipMultilineEncoding: trueOriginalSecret.skipMultilineEncoding, + skipMultilineEncoding: modSecret.skipMultilineEncoding + }), + ...(!isSameTags && { + originalTags: + trueOriginalSecret.tags?.map((tag) => ({ id: tag.id, slug: tag.slug })) || [], + tags: tags?.map((tag) => ({ id: tag.id, slug: tag.name || tag.slug || "" })) || [] + }), + ...(JSON.stringify(secretMetadata) !== + JSON.stringify(trueOriginalSecret.secretMetadata) && { + originalSecretMetadata: trueOriginalSecret.secretMetadata || [], + secretMetadata: secretMetadata || [] + }), + + timestamp: Date.now(), + resourceType: "secret", + existingSecret: orgSecret + }; + + addPendingChange(updateChange, { + workspaceId, + environment, + secretPath + }); + } + + if (!isReminderEvent) { + handlePopUpClose("secretDetail"); + } + if (cb) cb(); + return; + } + await handleSecretOperation("update", SecretType.Shared, oldKey, { value, tags: tagIds, @@ -314,12 +453,41 @@ export const SecretListView = ({ }); } }, - [environment, secretPath, isProtectedBranch] + [ + environment, + secretPath, + isProtectedBranch, + isBatchMode, + workspaceId, + addPendingChange, + pendingChanges.secrets + ] ); const handleSecretDelete = useCallback(async () => { - const { key, id: secretId } = popUp.deleteSecret?.data as SecretV3RawSanitized; + const { key, id: secretId, value } = popUp.deleteSecret?.data as SecretV3RawSanitized; try { + if (isBatchMode) { + const deleteChange: PendingSecretDelete = { + id: `${secretId}`, + type: PendingAction.Delete, + secretKey: key, + secretValue: value || "", + timestamp: Date.now(), + resourceType: "secret" + }; + + addPendingChange(deleteChange, { + workspaceId, + environment, + secretPath + }); + + handlePopUpClose("deleteSecret"); + handlePopUpClose("secretDetail"); + return; + } + await handleSecretOperation("delete", SecretType.Shared, key, { secretId }); // wrap this in another function and then reuse queryClient.invalidateQueries({ @@ -362,7 +530,10 @@ export const SecretListView = ({ (popUp.deleteSecret?.data as SecretV3RawSanitized)?.key, environment, secretPath, - isProtectedBranch + isProtectedBranch, + isBatchMode, + workspaceId, + addPendingChange ]); // for optimization on minimise re-rendering of secret items @@ -401,6 +572,8 @@ export const SecretListView = ({ value: secret.valueOverride ?? secret.value }) } + isPending={secret.isPending} + pendingAction={secret.pendingAction} /> ))} - + {name} @@ -141,7 +141,7 @@ export const SecretRotationItem = ({ { @@ -185,7 +184,6 @@ export const SecretRotationItem = ({ ariaLabel="Delete rotation" variant="plain" colorSchema="danger" - size="md" className="opacity-0 group-hover:opacity-100" onClick={(e) => { e.stopPropagation(); @@ -193,7 +191,7 @@ export const SecretRotationItem = ({ }} isDisabled={!isAllowed} > - + )} diff --git a/frontend/src/pages/secret-manager/SecretDashboardPage/route.tsx b/frontend/src/pages/secret-manager/SecretDashboardPage/route.tsx index e77120d7a..09970f698 100644 --- a/frontend/src/pages/secret-manager/SecretDashboardPage/route.tsx +++ b/frontend/src/pages/secret-manager/SecretDashboardPage/route.tsx @@ -13,7 +13,7 @@ const SecretDashboardPageQueryParamsSchema = z.object({ tags: z.string().catch("") }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/secrets/$envSlug" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/secrets/$envSlug" )({ component: SecretDashboardPage, validateSearch: zodValidator(SecretDashboardPageQueryParamsSchema), @@ -28,7 +28,7 @@ export const Route = createFileRoute( { label: "Secrets", link: linkOptions({ - to: "/projects/$projectId/secret-manager/overview", + to: "/projects/secret-management/$projectId/overview", params }) }, @@ -39,7 +39,7 @@ export const Route = createFileRoute( links: context.project.environments.map((el) => ({ label: el.name, link: linkOptions({ - to: "/projects/$projectId/secret-manager/secrets/$envSlug", + to: "/projects/secret-management/$projectId/secrets/$envSlug", params: { projectId: params.projectId, envSlug: el.slug diff --git a/frontend/src/pages/secret-manager/SecretRotationPage/SecretRotationPage.tsx b/frontend/src/pages/secret-manager/SecretRotationPage/SecretRotationPage.tsx index e41940380..51551999e 100644 --- a/frontend/src/pages/secret-manager/SecretRotationPage/SecretRotationPage.tsx +++ b/frontend/src/pages/secret-manager/SecretRotationPage/SecretRotationPage.tsx @@ -172,7 +172,7 @@ const Page = () => { PostgreSQL and Microsoft SQL Server Rotations can now be created from the{" "} Secret Manager Dashboard @@ -407,7 +407,7 @@ const Page = () => { Infisical is revamping its Secret Rotation experience. Navigate to the{" "} Secret Manager Dashboard @@ -424,7 +424,7 @@ const Page = () => { navigate({ - to: "/projects/$projectId/secret-manager/overview", + to: "/projects/secret-management/$projectId/overview", params: { projectId: currentWorkspace.id } }) } diff --git a/frontend/src/pages/secret-manager/SecretRotationPage/route.tsx b/frontend/src/pages/secret-manager/SecretRotationPage/route.tsx index 326ef5745..85fce6ccf 100644 --- a/frontend/src/pages/secret-manager/SecretRotationPage/route.tsx +++ b/frontend/src/pages/secret-manager/SecretRotationPage/route.tsx @@ -3,7 +3,7 @@ import { createFileRoute } from "@tanstack/react-router"; import { SecretRotationPage } from "./SecretRotationPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/secret-rotation" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/secret-rotation" )({ component: SecretRotationPage, beforeLoad: ({ context }) => { diff --git a/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncDestinationSection/BitbucketSyncDestinationSection.tsx b/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncDestinationSection/BitbucketSyncDestinationSection.tsx new file mode 100644 index 000000000..04999b969 --- /dev/null +++ b/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncDestinationSection/BitbucketSyncDestinationSection.tsx @@ -0,0 +1,22 @@ +import { GenericFieldLabel } from "@app/components/secret-syncs"; +import { TBitbucketSync } from "@app/hooks/api/secretSyncs/types/bitbucket-sync"; + +type Props = { + secretSync: TBitbucketSync; +}; + +export const BitbucketSyncDestinationSection = ({ secretSync }: Props) => { + const { + destinationConfig: { workspaceSlug, repositorySlug, environmentId } + } = secretSync; + + return ( + <> + {workspaceSlug} + {repositorySlug} + {environmentId && ( + {environmentId} + )} + > + ); +}; diff --git a/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncDestinationSection/SecretSyncDestinatonSection.tsx b/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncDestinationSection/SecretSyncDestinatonSection.tsx index e7230e815..44220c200 100644 --- a/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncDestinationSection/SecretSyncDestinatonSection.tsx +++ b/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncDestinationSection/SecretSyncDestinatonSection.tsx @@ -17,6 +17,7 @@ import { AwsSecretsManagerSyncDestinationSection } from "./AwsSecretsManagerSync import { AzureAppConfigurationSyncDestinationSection } from "./AzureAppConfigurationSyncDestinationSection"; import { AzureDevOpsSyncDestinationSection } from "./AzureDevOpsSyncDestinationSection"; import { AzureKeyVaultSyncDestinationSection } from "./AzureKeyVaultSyncDestinationSection"; +import { BitbucketSyncDestinationSection } from "./BitbucketSyncDestinationSection"; import { CamundaSyncDestinationSection } from "./CamundaSyncDestinationSection"; import { ChecklySyncDestinationSection } from "./ChecklySyncDestinationSection"; import { CloudflarePagesSyncDestinationSection } from "./CloudflarePagesSyncDestinationSection"; @@ -134,6 +135,9 @@ export const SecretSyncDestinationSection = ({ secretSync, onEditDestination }: case SecretSync.Supabase: DestinationComponents = ; break; + case SecretSync.Bitbucket: + DestinationComponents = ; + break; default: throw new Error(`Unhandled Destination Section components: ${destination}`); } diff --git a/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncOptionsSection/SecretSyncOptionsSection.tsx b/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncOptionsSection/SecretSyncOptionsSection.tsx index 3cc70ebcb..eb366952d 100644 --- a/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncOptionsSection/SecretSyncOptionsSection.tsx +++ b/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncOptionsSection/SecretSyncOptionsSection.tsx @@ -65,6 +65,7 @@ export const SecretSyncOptionsSection = ({ secretSync, onEditOptions }: Props) = case SecretSync.Railway: case SecretSync.Supabase: case SecretSync.Checkly: + case SecretSync.Bitbucket: AdditionalSyncOptionsComponent = null; break; default: diff --git a/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/route.tsx b/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/route.tsx index a184d22ff..b6e1ab4d5 100644 --- a/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/route.tsx +++ b/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { SecretSyncDetailsByIDPage } from "./SecretSyncDetailsByIDPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/secret-syncs/$destination/$syncId" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/secret-syncs/$destination/$syncId" )({ component: SecretSyncDetailsByIDPage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.SecretSyncs diff --git a/frontend/src/pages/secret-manager/SettingsPage/SettingsPage.tsx b/frontend/src/pages/secret-manager/SettingsPage/SettingsPage.tsx index 49bf7780e..d864d9a44 100644 --- a/frontend/src/pages/secret-manager/SettingsPage/SettingsPage.tsx +++ b/frontend/src/pages/secret-manager/SettingsPage/SettingsPage.tsx @@ -4,9 +4,10 @@ import { useTranslation } from "react-i18next"; import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2"; import { useWorkspace } from "@app/context"; import { ProjectVersion } from "@app/hooks/api/workspace/types"; +import { ProjectGeneralTab } from "@app/pages/project/SettingsPage/components/ProjectGeneralTab"; import { EncryptionTab } from "./components/EncryptionTab"; -import { ProjectGeneralTab } from "./components/ProjectGeneralTab"; +import { SecretSettingsTab } from "./components/ProjectGeneralTab"; import { WebhooksTab } from "./components/WebhooksTab"; import { WorkflowIntegrationTab } from "./components/WorkflowIntegrationSection"; @@ -15,6 +16,7 @@ export const SettingsPage = () => { const { currentWorkspace } = useWorkspace(); const tabs = [ { name: "General", key: "tab-project-general", Component: ProjectGeneralTab }, + { name: "Secrets Management", key: "tab-secret-general", Component: SecretSettingsTab }, { name: "Encryption", key: "tab-project-encryption", diff --git a/frontend/src/pages/secret-manager/SettingsPage/components/ProjectGeneralTab/ProjectGeneralTab.tsx b/frontend/src/pages/secret-manager/SettingsPage/components/ProjectGeneralTab/ProjectGeneralTab.tsx index 2973736f3..5f817a46a 100644 --- a/frontend/src/pages/secret-manager/SettingsPage/components/ProjectGeneralTab/ProjectGeneralTab.tsx +++ b/frontend/src/pages/secret-manager/SettingsPage/components/ProjectGeneralTab/ProjectGeneralTab.tsx @@ -6,7 +6,7 @@ import { SecretSharingSection } from "../SecretSharingSection"; import { SecretSnapshotsLegacySection } from "../SecretSnapshotsLegacySection"; import { SecretTagsSection } from "../SecretTagsSection"; -export const ProjectGeneralTab = () => { +export const SecretSettingsTab = () => { return ( diff --git a/frontend/src/pages/secret-manager/SettingsPage/components/ProjectGeneralTab/index.tsx b/frontend/src/pages/secret-manager/SettingsPage/components/ProjectGeneralTab/index.tsx index c6e611e0f..b32882dbe 100644 --- a/frontend/src/pages/secret-manager/SettingsPage/components/ProjectGeneralTab/index.tsx +++ b/frontend/src/pages/secret-manager/SettingsPage/components/ProjectGeneralTab/index.tsx @@ -1 +1 @@ -export { ProjectGeneralTab } from "./ProjectGeneralTab"; +export { SecretSettingsTab } from "./ProjectGeneralTab"; diff --git a/frontend/src/pages/secret-manager/SettingsPage/route.tsx b/frontend/src/pages/secret-manager/SettingsPage/route.tsx index f587ab680..d3343d668 100644 --- a/frontend/src/pages/secret-manager/SettingsPage/route.tsx +++ b/frontend/src/pages/secret-manager/SettingsPage/route.tsx @@ -3,7 +3,7 @@ import { createFileRoute } from "@tanstack/react-router"; import { SettingsPage } from "./SettingsPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/settings" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/settings" )({ component: SettingsPage, beforeLoad: ({ context }) => { diff --git a/frontend/src/pages/secret-manager/integrations/AwsParameterStoreAuthorizePage/AwsParameterStoreAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/AwsParameterStoreAuthorizePage/AwsParameterStoreAuthorizePage.tsx index 31702635a..e67e1e328 100644 --- a/frontend/src/pages/secret-manager/integrations/AwsParameterStoreAuthorizePage/AwsParameterStoreAuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/AwsParameterStoreAuthorizePage/AwsParameterStoreAuthorizePage.tsx @@ -68,7 +68,7 @@ export const AWSParameterStoreAuthorizeIntegrationPage = () => { }); navigate({ - to: "/projects/$projectId/secret-manager/integrations/aws-parameter-store/create", + to: "/projects/secret-management/$projectId/integrations/aws-parameter-store/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/AwsParameterStoreAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/AwsParameterStoreAuthorizePage/route.tsx index c1b38e13e..e8f023293 100644 --- a/frontend/src/pages/secret-manager/integrations/AwsParameterStoreAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/AwsParameterStoreAuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { AWSParameterStoreAuthorizeIntegrationPage } from "./AwsParameterStoreAuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-parameter-store/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/authorize" )({ component: AWSParameterStoreAuthorizeIntegrationPage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/AwsParameterStoreConfigurePage/AwsParamterStoreConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/AwsParameterStoreConfigurePage/AwsParamterStoreConfigurePage.tsx index 7c2448fe9..bbdd2d71b 100644 --- a/frontend/src/pages/secret-manager/integrations/AwsParameterStoreConfigurePage/AwsParamterStoreConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/AwsParameterStoreConfigurePage/AwsParamterStoreConfigurePage.tsx @@ -156,7 +156,7 @@ export const AWSParameterStoreConfigurePage = () => { setPathErrorText(""); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/AwsParameterStoreConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/AwsParameterStoreConfigurePage/route.tsx index 10a1fcfeb..44a52eec8 100644 --- a/frontend/src/pages/secret-manager/integrations/AwsParameterStoreConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/AwsParameterStoreConfigurePage/route.tsx @@ -11,7 +11,7 @@ const AwsParameterStoreConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-parameter-store/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/create" )({ component: AWSParameterStoreConfigurePage, validateSearch: zodValidator(AwsParameterStoreConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/AwsSecretManagerAuthorizePage/AwsSecretManagerAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/AwsSecretManagerAuthorizePage/AwsSecretManagerAuthorizePage.tsx index 3a4e2fdc0..bdc18d8dd 100644 --- a/frontend/src/pages/secret-manager/integrations/AwsSecretManagerAuthorizePage/AwsSecretManagerAuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/AwsSecretManagerAuthorizePage/AwsSecretManagerAuthorizePage.tsx @@ -66,7 +66,7 @@ export const AWSSecretManagerAuthorizePage = () => { }) }); navigate({ - to: "/projects/$projectId/secret-manager/integrations/aws-secret-manager/create", + to: "/projects/secret-management/$projectId/integrations/aws-secret-manager/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/AwsSecretManagerAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/AwsSecretManagerAuthorizePage/route.tsx index 06594c276..9f80bd3be 100644 --- a/frontend/src/pages/secret-manager/integrations/AwsSecretManagerAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/AwsSecretManagerAuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { AWSSecretManagerAuthorizePage } from "./AwsSecretManagerAuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-secret-manager/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/authorize" )({ component: AWSSecretManagerAuthorizePage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/AwsSecretManagerConfigurePage/AwsSecretManagerConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/AwsSecretManagerConfigurePage/AwsSecretManagerConfigurePage.tsx index 8503adb79..bd73fc596 100644 --- a/frontend/src/pages/secret-manager/integrations/AwsSecretManagerConfigurePage/AwsSecretManagerConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/AwsSecretManagerConfigurePage/AwsSecretManagerConfigurePage.tsx @@ -204,7 +204,7 @@ export const AwsSecretManagerConfigurePage = () => { }); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/AwsSecretManagerConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/AwsSecretManagerConfigurePage/route.tsx index ec636db09..a90f6c19f 100644 --- a/frontend/src/pages/secret-manager/integrations/AwsSecretManagerConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/AwsSecretManagerConfigurePage/route.tsx @@ -11,7 +11,7 @@ const AwsSecretManagerConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-secret-manager/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/create" )({ component: AwsSecretManagerConfigurePage, validateSearch: zodValidator(AwsSecretManagerConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/AzureAppConfigurationConfigurePage/AzureAppConfigurationConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/AzureAppConfigurationConfigurePage/AzureAppConfigurationConfigurePage.tsx index f4c3a76d0..1e107807e 100644 --- a/frontend/src/pages/secret-manager/integrations/AzureAppConfigurationConfigurePage/AzureAppConfigurationConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/AzureAppConfigurationConfigurePage/AzureAppConfigurationConfigurePage.tsx @@ -131,7 +131,7 @@ export const AzureAppConfigurationConfigurePage = () => { }); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/AzureAppConfigurationConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/AzureAppConfigurationConfigurePage/route.tsx index e773ef660..d83085c4c 100644 --- a/frontend/src/pages/secret-manager/integrations/AzureAppConfigurationConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/AzureAppConfigurationConfigurePage/route.tsx @@ -11,7 +11,7 @@ const AzureAppConfigurationPageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-app-configuration/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/create" )({ component: AzureAppConfigurationConfigurePage, validateSearch: zodValidator(AzureAppConfigurationPageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/AzureAppConfigurationOauthCallbackPage/AzureAppConfigurationOauthCallbackPage.tsx b/frontend/src/pages/secret-manager/integrations/AzureAppConfigurationOauthCallbackPage/AzureAppConfigurationOauthCallbackPage.tsx index 1eba3ccf1..d15fea903 100644 --- a/frontend/src/pages/secret-manager/integrations/AzureAppConfigurationOauthCallbackPage/AzureAppConfigurationOauthCallbackPage.tsx +++ b/frontend/src/pages/secret-manager/integrations/AzureAppConfigurationOauthCallbackPage/AzureAppConfigurationOauthCallbackPage.tsx @@ -28,7 +28,7 @@ export const AzureAppConfigurationOauthCallbackPage = () => { }); navigate({ - to: "/projects/$projectId/secret-manager/integrations/azure-app-configuration/create", + to: "/projects/secret-management/$projectId/integrations/azure-app-configuration/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/AzureAppConfigurationOauthCallbackPage/route.tsx b/frontend/src/pages/secret-manager/integrations/AzureAppConfigurationOauthCallbackPage/route.tsx index 7b4772d91..b8bf9a072 100644 --- a/frontend/src/pages/secret-manager/integrations/AzureAppConfigurationOauthCallbackPage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/AzureAppConfigurationOauthCallbackPage/route.tsx @@ -12,7 +12,7 @@ export const AzureAppConfigurationOauthCallbackPageQueryParamsSchema = z.object( }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-app-configuration/oauth2/callback" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/oauth2/callback" )({ component: AzureAppConfigurationOauthCallbackPage, validateSearch: zodValidator(AzureAppConfigurationOauthCallbackPageQueryParamsSchema), @@ -23,7 +23,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/AzureDevopsAuthorizePage/AzureDevopsAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/AzureDevopsAuthorizePage/AzureDevopsAuthorizePage.tsx index 3bfbd4a54..25cc9c617 100644 --- a/frontend/src/pages/secret-manager/integrations/AzureDevopsAuthorizePage/AzureDevopsAuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/AzureDevopsAuthorizePage/AzureDevopsAuthorizePage.tsx @@ -39,7 +39,7 @@ export const AzureDevopsAuthorizePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations/azure-devops/create", + to: "/projects/secret-management/$projectId/integrations/azure-devops/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/AzureDevopsAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/AzureDevopsAuthorizePage/route.tsx index 8a27db56a..075171776 100644 --- a/frontend/src/pages/secret-manager/integrations/AzureDevopsAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/AzureDevopsAuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { AzureDevopsAuthorizePage } from "./AzureDevopsAuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-devops/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/authorize" )({ component: AzureDevopsAuthorizePage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/AzureDevopsConfigurePage/AzureDevopsConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/AzureDevopsConfigurePage/AzureDevopsConfigurePage.tsx index a99560941..b06859e1f 100644 --- a/frontend/src/pages/secret-manager/integrations/AzureDevopsConfigurePage/AzureDevopsConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/AzureDevopsConfigurePage/AzureDevopsConfigurePage.tsx @@ -80,7 +80,7 @@ export const AzureDevopsConfigurePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/AzureDevopsConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/AzureDevopsConfigurePage/route.tsx index 1f3da6116..88e61f5f1 100644 --- a/frontend/src/pages/secret-manager/integrations/AzureDevopsConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/AzureDevopsConfigurePage/route.tsx @@ -11,7 +11,7 @@ const AzureDevopsConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-devops/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/create" )({ component: AzureDevopsConfigurePage, validateSearch: zodValidator(AzureDevopsConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/AzureKeyVaultAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/AzureKeyVaultAuthorizePage/route.tsx index 4062139bb..8127e0a4e 100644 --- a/frontend/src/pages/secret-manager/integrations/AzureKeyVaultAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/AzureKeyVaultAuthorizePage/route.tsx @@ -11,7 +11,7 @@ const PageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-key-vault/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/authorize" )({ component: AzureKeyVaultAuthorizePage, validateSearch: PageQueryParamsSchema, @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/AzureKeyVaultConfigurePage/AzureKeyVaultConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/AzureKeyVaultConfigurePage/AzureKeyVaultConfigurePage.tsx index 4d7af91a1..e5ccd3dfa 100644 --- a/frontend/src/pages/secret-manager/integrations/AzureKeyVaultConfigurePage/AzureKeyVaultConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/AzureKeyVaultConfigurePage/AzureKeyVaultConfigurePage.tsx @@ -88,7 +88,7 @@ export const AzureKeyVaultConfigurePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/AzureKeyVaultConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/AzureKeyVaultConfigurePage/route.tsx index 49b091efd..375ef1929 100644 --- a/frontend/src/pages/secret-manager/integrations/AzureKeyVaultConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/AzureKeyVaultConfigurePage/route.tsx @@ -11,7 +11,7 @@ const AzureKeyVaultConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-key-vault/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/create" )({ component: AzureKeyVaultConfigurePage, validateSearch: zodValidator(AzureKeyVaultConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/AzureKeyVaultOauthCallbackPage/AzureKeyVaultOauthCallback.tsx b/frontend/src/pages/secret-manager/integrations/AzureKeyVaultOauthCallbackPage/AzureKeyVaultOauthCallback.tsx index e4b38cf76..ef98d1cba 100644 --- a/frontend/src/pages/secret-manager/integrations/AzureKeyVaultOauthCallbackPage/AzureKeyVaultOauthCallback.tsx +++ b/frontend/src/pages/secret-manager/integrations/AzureKeyVaultOauthCallbackPage/AzureKeyVaultOauthCallback.tsx @@ -28,7 +28,7 @@ export const AzureKeyVaultOauthCallbackPage = () => { }); navigate({ - to: "/projects/$projectId/secret-manager/integrations/azure-key-vault/create", + to: "/projects/secret-management/$projectId/integrations/azure-key-vault/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/AzureKeyVaultOauthCallbackPage/route.tsx b/frontend/src/pages/secret-manager/integrations/AzureKeyVaultOauthCallbackPage/route.tsx index 315243d11..a55e4d0a3 100644 --- a/frontend/src/pages/secret-manager/integrations/AzureKeyVaultOauthCallbackPage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/AzureKeyVaultOauthCallbackPage/route.tsx @@ -12,7 +12,7 @@ export const AzureKeyVaultOauthCallbackQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-key-vault/oauth2/callback" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/oauth2/callback" )({ component: AzureKeyVaultOauthCallbackPage, validateSearch: zodValidator(AzureKeyVaultOauthCallbackQueryParamsSchema), @@ -23,7 +23,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/BitbucketConfigurePage/BitbucketConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/BitbucketConfigurePage/BitbucketConfigurePage.tsx index 291dec6ca..10dafdb76 100644 --- a/frontend/src/pages/secret-manager/integrations/BitbucketConfigurePage/BitbucketConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/BitbucketConfigurePage/BitbucketConfigurePage.tsx @@ -148,7 +148,7 @@ export const BitbucketConfigurePage = () => { text: "Successfully created integration" }); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/BitbucketConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/BitbucketConfigurePage/route.tsx index c3ed59f8d..a784712a1 100644 --- a/frontend/src/pages/secret-manager/integrations/BitbucketConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/BitbucketConfigurePage/route.tsx @@ -11,7 +11,7 @@ const BitbucketConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/bitbucket/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/create" )({ component: BitbucketConfigurePage, validateSearch: zodValidator(BitbucketConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/BitbucketOauthCallbackPage/BitbucketOauthCallbackPage.tsx b/frontend/src/pages/secret-manager/integrations/BitbucketOauthCallbackPage/BitbucketOauthCallbackPage.tsx index 386d22a69..1e3d302f2 100644 --- a/frontend/src/pages/secret-manager/integrations/BitbucketOauthCallbackPage/BitbucketOauthCallbackPage.tsx +++ b/frontend/src/pages/secret-manager/integrations/BitbucketOauthCallbackPage/BitbucketOauthCallbackPage.tsx @@ -27,7 +27,7 @@ export const BitbucketOauthCallbackPage = () => { }); navigate({ - to: "/projects/$projectId/secret-manager/integrations/bitbucket/create", + to: "/projects/secret-management/$projectId/integrations/bitbucket/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/BitbucketOauthCallbackPage/route.tsx b/frontend/src/pages/secret-manager/integrations/BitbucketOauthCallbackPage/route.tsx index 2d6581a81..7be4e6842 100644 --- a/frontend/src/pages/secret-manager/integrations/BitbucketOauthCallbackPage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/BitbucketOauthCallbackPage/route.tsx @@ -12,7 +12,7 @@ export const BitbucketOauthCallbackQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/bitbucket/oauth2/callback" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/oauth2/callback" )({ component: BitbucketOauthCallbackPage, validateSearch: zodValidator(BitbucketOauthCallbackQueryParamsSchema), @@ -23,7 +23,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/ChecklyAuthorizePage/ChecklyAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/ChecklyAuthorizePage/ChecklyAuthorizePage.tsx index b2e4baa25..5dd711fc0 100644 --- a/frontend/src/pages/secret-manager/integrations/ChecklyAuthorizePage/ChecklyAuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/ChecklyAuthorizePage/ChecklyAuthorizePage.tsx @@ -36,7 +36,7 @@ export const ChecklyAuthorizePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations/checkly/create", + to: "/projects/secret-management/$projectId/integrations/checkly/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/ChecklyAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/ChecklyAuthorizePage/route.tsx index 04de97d8c..3bfce7977 100644 --- a/frontend/src/pages/secret-manager/integrations/ChecklyAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/ChecklyAuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { ChecklyAuthorizePage } from "./ChecklyAuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/checkly/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/authorize" )({ component: ChecklyAuthorizePage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/ChecklyConfigurePage/ChecklyConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/ChecklyConfigurePage/ChecklyConfigurePage.tsx index 357b179c1..2e02f7cf2 100644 --- a/frontend/src/pages/secret-manager/integrations/ChecklyConfigurePage/ChecklyConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/ChecklyConfigurePage/ChecklyConfigurePage.tsx @@ -113,7 +113,7 @@ export const ChecklyConfigurePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/ChecklyConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/ChecklyConfigurePage/route.tsx index 7c7b852f0..d87b8498a 100644 --- a/frontend/src/pages/secret-manager/integrations/ChecklyConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/ChecklyConfigurePage/route.tsx @@ -11,7 +11,7 @@ const ChecklyConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/checkly/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/create" )({ component: ChecklyConfigurePage, validateSearch: zodValidator(ChecklyConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/CircleCIAuthorizePage/CircleCIAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/CircleCIAuthorizePage/CircleCIAuthorizePage.tsx index c4b8ded6e..e64227fc3 100644 --- a/frontend/src/pages/secret-manager/integrations/CircleCIAuthorizePage/CircleCIAuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/CircleCIAuthorizePage/CircleCIAuthorizePage.tsx @@ -36,7 +36,7 @@ export const CircleCIAuthorizePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations/circleci/create", + to: "/projects/secret-management/$projectId/integrations/circleci/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/CircleCIAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/CircleCIAuthorizePage/route.tsx index c00bb9e0a..ced9f6077 100644 --- a/frontend/src/pages/secret-manager/integrations/CircleCIAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/CircleCIAuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { CircleCIAuthorizePage } from "./CircleCIAuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/circleci/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/authorize" )({ component: CircleCIAuthorizePage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/CircleCIConfigurePage/CircleCIConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/CircleCIConfigurePage/CircleCIConfigurePage.tsx index 0b839bac3..f03f35af8 100644 --- a/frontend/src/pages/secret-manager/integrations/CircleCIConfigurePage/CircleCIConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/CircleCIConfigurePage/CircleCIConfigurePage.tsx @@ -103,7 +103,7 @@ export const CircleCIConfigurePage = () => { text: "Successfully created integration" }); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/CircleCIConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/CircleCIConfigurePage/route.tsx index 676eb06de..e22fdf9be 100644 --- a/frontend/src/pages/secret-manager/integrations/CircleCIConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/CircleCIConfigurePage/route.tsx @@ -11,7 +11,7 @@ const CircleCIConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/circleci/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/create" )({ component: CircleCIConfigurePage, validateSearch: zodValidator(CircleCIConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/Cloud66AuthorizePage/Cloud66AuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/Cloud66AuthorizePage/Cloud66AuthorizePage.tsx index 5f569d536..8fc9dd5ca 100644 --- a/frontend/src/pages/secret-manager/integrations/Cloud66AuthorizePage/Cloud66AuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/Cloud66AuthorizePage/Cloud66AuthorizePage.tsx @@ -34,7 +34,7 @@ export const Cloud66AuthorizePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations/cloud-66/create", + to: "/projects/secret-management/$projectId/integrations/cloud-66/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/Cloud66AuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/Cloud66AuthorizePage/route.tsx index e5db08e19..929f854f4 100644 --- a/frontend/src/pages/secret-manager/integrations/Cloud66AuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/Cloud66AuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { Cloud66AuthorizePage } from "./Cloud66AuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloud-66/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/authorize" )({ component: Cloud66AuthorizePage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/Cloud66ConfigurePage/Cloud66ConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/Cloud66ConfigurePage/Cloud66ConfigurePage.tsx index 0e12890ce..6de5e3bc3 100644 --- a/frontend/src/pages/secret-manager/integrations/Cloud66ConfigurePage/Cloud66ConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/Cloud66ConfigurePage/Cloud66ConfigurePage.tsx @@ -75,7 +75,7 @@ export const Cloud66ConfigurePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/Cloud66ConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/Cloud66ConfigurePage/route.tsx index f7e03c8e5..3cd1ea6f6 100644 --- a/frontend/src/pages/secret-manager/integrations/Cloud66ConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/Cloud66ConfigurePage/route.tsx @@ -11,7 +11,7 @@ const Cloud66ConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloud-66/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/create" )({ component: Cloud66ConfigurePage, validateSearch: zodValidator(Cloud66ConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/CloudflarePagesAuthorizePage/CloudflarePagesAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/CloudflarePagesAuthorizePage/CloudflarePagesAuthorizePage.tsx index b643f03d9..16feba283 100644 --- a/frontend/src/pages/secret-manager/integrations/CloudflarePagesAuthorizePage/CloudflarePagesAuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/CloudflarePagesAuthorizePage/CloudflarePagesAuthorizePage.tsx @@ -41,7 +41,7 @@ export const CloudflarePagesAuthorizePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations/cloudflare-pages/create", + to: "/projects/secret-management/$projectId/integrations/cloudflare-pages/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/CloudflarePagesAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/CloudflarePagesAuthorizePage/route.tsx index 3186bde97..1bd26c9d6 100644 --- a/frontend/src/pages/secret-manager/integrations/CloudflarePagesAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/CloudflarePagesAuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { CloudflarePagesAuthorizePage } from "./CloudflarePagesAuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-pages/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/authorize" )({ component: CloudflarePagesAuthorizePage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/CloudflarePagesConfigurePage/CloudflarePagesConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/CloudflarePagesConfigurePage/CloudflarePagesConfigurePage.tsx index 471e686af..1ff6e75d5 100644 --- a/frontend/src/pages/secret-manager/integrations/CloudflarePagesConfigurePage/CloudflarePagesConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/CloudflarePagesConfigurePage/CloudflarePagesConfigurePage.tsx @@ -94,7 +94,7 @@ export const CloudflarePagesConfigurePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/CloudflarePagesConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/CloudflarePagesConfigurePage/route.tsx index 58e5e2bed..b597426a8 100644 --- a/frontend/src/pages/secret-manager/integrations/CloudflarePagesConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/CloudflarePagesConfigurePage/route.tsx @@ -11,7 +11,7 @@ const CloudflarePagesConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-pages/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/create" )({ component: CloudflarePagesConfigurePage, validateSearch: zodValidator(CloudflarePagesConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/CloudflareWorkersAuthorizePage/CloudflareWorkersAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/CloudflareWorkersAuthorizePage/CloudflareWorkersAuthorizePage.tsx index 128d96eef..e2829c76a 100644 --- a/frontend/src/pages/secret-manager/integrations/CloudflareWorkersAuthorizePage/CloudflareWorkersAuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/CloudflareWorkersAuthorizePage/CloudflareWorkersAuthorizePage.tsx @@ -41,7 +41,7 @@ export const CloudflareWorkersAuthorizePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations/cloudflare-workers/create", + to: "/projects/secret-management/$projectId/integrations/cloudflare-workers/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/CloudflareWorkersAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/CloudflareWorkersAuthorizePage/route.tsx index 1aff2b85e..16c5fb28f 100644 --- a/frontend/src/pages/secret-manager/integrations/CloudflareWorkersAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/CloudflareWorkersAuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { CloudflareWorkersAuthorizePage } from "./CloudflareWorkersAuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-workers/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/authorize" )({ component: CloudflareWorkersAuthorizePage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/CloudflareWorkersConfigurePage/CloudflareWorkersConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/CloudflareWorkersConfigurePage/CloudflareWorkersConfigurePage.tsx index 431e3aa12..bfc4b766a 100644 --- a/frontend/src/pages/secret-manager/integrations/CloudflareWorkersConfigurePage/CloudflareWorkersConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/CloudflareWorkersConfigurePage/CloudflareWorkersConfigurePage.tsx @@ -67,7 +67,7 @@ export const CloudflareWorkersConfigurePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/CloudflareWorkersConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/CloudflareWorkersConfigurePage/route.tsx index 876b8ca49..39c043934 100644 --- a/frontend/src/pages/secret-manager/integrations/CloudflareWorkersConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/CloudflareWorkersConfigurePage/route.tsx @@ -11,7 +11,7 @@ const CloudflareWorkersConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-workers/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/create" )({ component: CloudflareWorkersConfigurePage, validateSearch: zodValidator(CloudflareWorkersConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/CodefreshAuthorizePage/CodefreshAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/CodefreshAuthorizePage/CodefreshAuthorizePage.tsx index a7aa9ee91..02e0d1378 100644 --- a/frontend/src/pages/secret-manager/integrations/CodefreshAuthorizePage/CodefreshAuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/CodefreshAuthorizePage/CodefreshAuthorizePage.tsx @@ -33,7 +33,7 @@ export const CodefreshAuthorizePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations/codefresh/create", + to: "/projects/secret-management/$projectId/integrations/codefresh/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/CodefreshAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/CodefreshAuthorizePage/route.tsx index 907ad45ad..44ac8efd8 100644 --- a/frontend/src/pages/secret-manager/integrations/CodefreshAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/CodefreshAuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { CodefreshAuthorizePage } from "./CodefreshAuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/codefresh/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/authorize" )({ component: CodefreshAuthorizePage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/CodefreshConfigurePage/CodefreshConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/CodefreshConfigurePage/CodefreshConfigurePage.tsx index d9e724fe7..e99ad4ea8 100644 --- a/frontend/src/pages/secret-manager/integrations/CodefreshConfigurePage/CodefreshConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/CodefreshConfigurePage/CodefreshConfigurePage.tsx @@ -71,7 +71,7 @@ export const CodefreshConfigurePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/CodefreshConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/CodefreshConfigurePage/route.tsx index 68711ef5b..9576d9175 100644 --- a/frontend/src/pages/secret-manager/integrations/CodefreshConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/CodefreshConfigurePage/route.tsx @@ -11,7 +11,7 @@ const CodefreshConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/codefresh/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/create" )({ component: CodefreshConfigurePage, validateSearch: zodValidator(CodefreshConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/DatabricksAuthorizePage/DatabricksAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/DatabricksAuthorizePage/DatabricksAuthorizePage.tsx index a3553ea16..25de9cd24 100644 --- a/frontend/src/pages/secret-manager/integrations/DatabricksAuthorizePage/DatabricksAuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/DatabricksAuthorizePage/DatabricksAuthorizePage.tsx @@ -40,7 +40,7 @@ export const DatabricksAuthorizePage = () => { }); navigate({ - to: "/projects/$projectId/secret-manager/integrations/databricks/create", + to: "/projects/secret-management/$projectId/integrations/databricks/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/DatabricksAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/DatabricksAuthorizePage/route.tsx index 3882a388b..5f05a78d9 100644 --- a/frontend/src/pages/secret-manager/integrations/DatabricksAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/DatabricksAuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { DatabricksAuthorizePage } from "./DatabricksAuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/databricks/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/authorize" )({ component: DatabricksAuthorizePage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/DatabricksConfigurePage/DatabricksConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/DatabricksConfigurePage/DatabricksConfigurePage.tsx index 87dba7c21..0f3d09728 100644 --- a/frontend/src/pages/secret-manager/integrations/DatabricksConfigurePage/DatabricksConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/DatabricksConfigurePage/DatabricksConfigurePage.tsx @@ -87,7 +87,7 @@ export const DatabricksConfigurePage = () => { }); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/DatabricksConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/DatabricksConfigurePage/route.tsx index 6fb3bc786..c84dbd55d 100644 --- a/frontend/src/pages/secret-manager/integrations/DatabricksConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/DatabricksConfigurePage/route.tsx @@ -11,7 +11,7 @@ const DatabricksConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/databricks/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/create" )({ component: DatabricksConfigurePage, validateSearch: zodValidator(DatabricksConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/DigitalOceanAppPlatformAuthorizePage/DigitalOceanAppPlatformAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/DigitalOceanAppPlatformAuthorizePage/DigitalOceanAppPlatformAuthorizePage.tsx index 892fa5b8c..3910dac15 100644 --- a/frontend/src/pages/secret-manager/integrations/DigitalOceanAppPlatformAuthorizePage/DigitalOceanAppPlatformAuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/DigitalOceanAppPlatformAuthorizePage/DigitalOceanAppPlatformAuthorizePage.tsx @@ -33,7 +33,7 @@ export const DigitalOceanAppPlatformAuthorizePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations/digital-ocean-app-platform/create", + to: "/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/DigitalOceanAppPlatformAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/DigitalOceanAppPlatformAuthorizePage/route.tsx index d95bf80f3..48284e9ae 100644 --- a/frontend/src/pages/secret-manager/integrations/DigitalOceanAppPlatformAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/DigitalOceanAppPlatformAuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { DigitalOceanAppPlatformAuthorizePage } from "./DigitalOceanAppPlatformAuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/digital-ocean-app-platform/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/authorize" )({ component: DigitalOceanAppPlatformAuthorizePage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/DigitalOceanAppPlatformConfigurePage/DigitalOceanAppPlatformConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/DigitalOceanAppPlatformConfigurePage/DigitalOceanAppPlatformConfigurePage.tsx index 4402a17eb..e88d98976 100644 --- a/frontend/src/pages/secret-manager/integrations/DigitalOceanAppPlatformConfigurePage/DigitalOceanAppPlatformConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/DigitalOceanAppPlatformConfigurePage/DigitalOceanAppPlatformConfigurePage.tsx @@ -72,7 +72,7 @@ export const DigitalOceanAppPlatformConfigurePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/DigitalOceanAppPlatformConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/DigitalOceanAppPlatformConfigurePage/route.tsx index 491a74172..40ce9eb5c 100644 --- a/frontend/src/pages/secret-manager/integrations/DigitalOceanAppPlatformConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/DigitalOceanAppPlatformConfigurePage/route.tsx @@ -11,7 +11,7 @@ const DigitalOceanAppPlatformConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/digital-ocean-app-platform/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/create" )({ component: DigitalOceanAppPlatformConfigurePage, validateSearch: zodValidator(DigitalOceanAppPlatformConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/FlyioAuthorizePage/FlyioAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/FlyioAuthorizePage/FlyioAuthorizePage.tsx index 15150a7e8..5fa42df52 100644 --- a/frontend/src/pages/secret-manager/integrations/FlyioAuthorizePage/FlyioAuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/FlyioAuthorizePage/FlyioAuthorizePage.tsx @@ -44,7 +44,7 @@ export const FlyioAuthorizePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations/flyio/create", + to: "/projects/secret-management/$projectId/integrations/flyio/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/FlyioAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/FlyioAuthorizePage/route.tsx index 138badee4..d90acff21 100644 --- a/frontend/src/pages/secret-manager/integrations/FlyioAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/FlyioAuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { FlyioAuthorizePage } from "./FlyioAuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/flyio/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/authorize" )({ component: FlyioAuthorizePage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/FlyioConfigurePage/FlyioConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/FlyioConfigurePage/FlyioConfigurePage.tsx index c8bebd9ce..0beb61bdf 100644 --- a/frontend/src/pages/secret-manager/integrations/FlyioConfigurePage/FlyioConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/FlyioConfigurePage/FlyioConfigurePage.tsx @@ -86,7 +86,7 @@ export const FlyioConfigurePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/FlyioConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/FlyioConfigurePage/route.tsx index 057f2ffbe..4211c37a7 100644 --- a/frontend/src/pages/secret-manager/integrations/FlyioConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/FlyioConfigurePage/route.tsx @@ -11,7 +11,7 @@ const FlyioConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/flyio/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/create" )({ component: FlyioConfigurePage, validateSearch: zodValidator(FlyioConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/GcpSecretManagerAuthorizePage/GcpSecretManagerAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/GcpSecretManagerAuthorizePage/GcpSecretManagerAuthorizePage.tsx index e332e2507..044be41c9 100644 --- a/frontend/src/pages/secret-manager/integrations/GcpSecretManagerAuthorizePage/GcpSecretManagerAuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/GcpSecretManagerAuthorizePage/GcpSecretManagerAuthorizePage.tsx @@ -70,7 +70,7 @@ export const GcpSecretManagerAuthorizePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations/gcp-secret-manager/create", + to: "/projects/secret-management/$projectId/integrations/gcp-secret-manager/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/GcpSecretManagerAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/GcpSecretManagerAuthorizePage/route.tsx index 40534b8d1..1e7e7d4a8 100644 --- a/frontend/src/pages/secret-manager/integrations/GcpSecretManagerAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/GcpSecretManagerAuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { GcpSecretManagerAuthorizePage } from "./GcpSecretManagerAuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gcp-secret-manager/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/authorize" )({ component: GcpSecretManagerAuthorizePage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/GcpSecretManagerConfigurePage/GcpSecretManagerConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/GcpSecretManagerConfigurePage/GcpSecretManagerConfigurePage.tsx index 15480e983..c4f8403bd 100644 --- a/frontend/src/pages/secret-manager/integrations/GcpSecretManagerConfigurePage/GcpSecretManagerConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/GcpSecretManagerConfigurePage/GcpSecretManagerConfigurePage.tsx @@ -151,7 +151,7 @@ export const GcpSecretManagerConfigurePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/GcpSecretManagerConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/GcpSecretManagerConfigurePage/route.tsx index 47f8ec2f9..4a925a2b2 100644 --- a/frontend/src/pages/secret-manager/integrations/GcpSecretManagerConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/GcpSecretManagerConfigurePage/route.tsx @@ -11,7 +11,7 @@ const GcpConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gcp-secret-manager/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/create" )({ component: GcpSecretManagerConfigurePage, validateSearch: zodValidator(GcpConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/GcpSecretManagerOauthCallbackPage/GcpSecretManagerOauthCallbackPage.tsx b/frontend/src/pages/secret-manager/integrations/GcpSecretManagerOauthCallbackPage/GcpSecretManagerOauthCallbackPage.tsx index 7672042c9..67cb0fac5 100644 --- a/frontend/src/pages/secret-manager/integrations/GcpSecretManagerOauthCallbackPage/GcpSecretManagerOauthCallbackPage.tsx +++ b/frontend/src/pages/secret-manager/integrations/GcpSecretManagerOauthCallbackPage/GcpSecretManagerOauthCallbackPage.tsx @@ -28,7 +28,7 @@ export const GcpSecretManagerOauthCallbackPage = () => { }); navigate({ - to: "/projects/$projectId/secret-manager/integrations/gcp-secret-manager/create", + to: "/projects/secret-management/$projectId/integrations/gcp-secret-manager/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/GcpSecretManagerOauthCallbackPage/route.tsx b/frontend/src/pages/secret-manager/integrations/GcpSecretManagerOauthCallbackPage/route.tsx index 901d68883..f449f75ad 100644 --- a/frontend/src/pages/secret-manager/integrations/GcpSecretManagerOauthCallbackPage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/GcpSecretManagerOauthCallbackPage/route.tsx @@ -12,7 +12,7 @@ export const GcpSecretManagerOAuthCallbackPageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gcp-secret-manager/oauth2/callback" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/oauth2/callback" )({ component: GcpSecretManagerOauthCallbackPage, validateSearch: zodValidator(GcpSecretManagerOAuthCallbackPageQueryParamsSchema), @@ -23,7 +23,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/GithubAuthorizePage/GithubAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/GithubAuthorizePage/GithubAuthorizePage.tsx index 84e0b10b8..623c5762c 100644 --- a/frontend/src/pages/secret-manager/integrations/GithubAuthorizePage/GithubAuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/GithubAuthorizePage/GithubAuthorizePage.tsx @@ -82,7 +82,7 @@ export const GithubAuthorizePage = () => { onClick={() => { if (selectedAuthMethod === AuthMethod.APP) { navigate({ - to: "/projects/$projectId/secret-manager/integrations/select-integration-auth", + to: "/projects/secret-management/$projectId/integrations/select-integration-auth", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/GithubAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/GithubAuthorizePage/route.tsx index c203641c9..b9cce03cb 100644 --- a/frontend/src/pages/secret-manager/integrations/GithubAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/GithubAuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { GithubAuthorizePage } from "./GithubAuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/github/auth-mode-selection" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/auth-mode-selection" )({ component: GithubAuthorizePage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/GithubConfigurePage/GithubConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/GithubConfigurePage/GithubConfigurePage.tsx index c4a611a66..aa71c793e 100644 --- a/frontend/src/pages/secret-manager/integrations/GithubConfigurePage/GithubConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/GithubConfigurePage/GithubConfigurePage.tsx @@ -267,7 +267,7 @@ export const GithubConfigurePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/GithubConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/GithubConfigurePage/route.tsx index d01447a66..12135432f 100644 --- a/frontend/src/pages/secret-manager/integrations/GithubConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/GithubConfigurePage/route.tsx @@ -11,7 +11,7 @@ const GithubConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/github/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/create" )({ component: GithubConfigurePage, validateSearch: zodValidator(GithubConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/GithubOauthCallbackPage/GithubOauthCallbackPage.tsx b/frontend/src/pages/secret-manager/integrations/GithubOauthCallbackPage/GithubOauthCallbackPage.tsx index d7e55e70c..66520e7f5 100644 --- a/frontend/src/pages/secret-manager/integrations/GithubOauthCallbackPage/GithubOauthCallbackPage.tsx +++ b/frontend/src/pages/secret-manager/integrations/GithubOauthCallbackPage/GithubOauthCallbackPage.tsx @@ -36,7 +36,7 @@ export const GithubOauthCallbackPage = () => { }); navigate({ - to: "/projects/$projectId/secret-manager/integrations/github/create", + to: "/projects/secret-management/$projectId/integrations/github/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/GithubOauthCallbackPage/route.tsx b/frontend/src/pages/secret-manager/integrations/GithubOauthCallbackPage/route.tsx index 2652d2acf..af5d661fd 100644 --- a/frontend/src/pages/secret-manager/integrations/GithubOauthCallbackPage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/GithubOauthCallbackPage/route.tsx @@ -13,7 +13,7 @@ export const GithubOAuthCallbackPageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/github/oauth2/callback" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/oauth2/callback" )({ component: GithubOauthCallbackPage, validateSearch: zodValidator(GithubOAuthCallbackPageQueryParamsSchema), @@ -24,7 +24,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/GitlabAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/GitlabAuthorizePage/route.tsx index 817b8c9cc..7e3b776a5 100644 --- a/frontend/src/pages/secret-manager/integrations/GitlabAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/GitlabAuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { GitlabAuthorizePage } from "./GitlabAuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gitlab/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/authorize" )({ component: GitlabAuthorizePage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/GitlabConfigurePage/GitlabConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/GitlabConfigurePage/GitlabConfigurePage.tsx index 458296fd4..6fb388b71 100644 --- a/frontend/src/pages/secret-manager/integrations/GitlabConfigurePage/GitlabConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/GitlabConfigurePage/GitlabConfigurePage.tsx @@ -175,7 +175,7 @@ export const GitlabConfigurePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/GitlabConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/GitlabConfigurePage/route.tsx index fd473646d..da6d78761 100644 --- a/frontend/src/pages/secret-manager/integrations/GitlabConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/GitlabConfigurePage/route.tsx @@ -11,7 +11,7 @@ const GitlabConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gitlab/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/create" )({ component: GitlabConfigurePage, validateSearch: zodValidator(GitlabConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/GitlabOauthCallbackPage/route.tsx b/frontend/src/pages/secret-manager/integrations/GitlabOauthCallbackPage/route.tsx index 8ab1686be..459cdbcdb 100644 --- a/frontend/src/pages/secret-manager/integrations/GitlabOauthCallbackPage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/GitlabOauthCallbackPage/route.tsx @@ -12,7 +12,7 @@ export const GitlabOAuthCallbackPageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gitlab/oauth2/callback" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/oauth2/callback" )({ component: GitLabOAuthCallbackPage, validateSearch: zodValidator(GitlabOAuthCallbackPageQueryParamsSchema), @@ -23,7 +23,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/HashicorpVaultAuthorizePage/HashicorpVaultAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/HashicorpVaultAuthorizePage/HashicorpVaultAuthorizePage.tsx index e56b27f8d..ae200968a 100644 --- a/frontend/src/pages/secret-manager/integrations/HashicorpVaultAuthorizePage/HashicorpVaultAuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/HashicorpVaultAuthorizePage/HashicorpVaultAuthorizePage.tsx @@ -51,7 +51,7 @@ export const HashicorpVaultAuthorizePage = () => { namespace: formData.vaultNamespace }); navigate({ - to: "/projects/$projectId/secret-manager/integrations/hashicorp-vault/create", + to: "/projects/secret-management/$projectId/integrations/hashicorp-vault/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/HashicorpVaultAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/HashicorpVaultAuthorizePage/route.tsx index ffebf25ad..54f92f66f 100644 --- a/frontend/src/pages/secret-manager/integrations/HashicorpVaultAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/HashicorpVaultAuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { HashicorpVaultAuthorizePage } from "./HashicorpVaultAuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hashicorp-vault/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/authorize" )({ component: HashicorpVaultAuthorizePage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/HashicorpVaultConfigurePage/HashicorpVaultConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/HashicorpVaultConfigurePage/HashicorpVaultConfigurePage.tsx index fe1539087..af9af585e 100644 --- a/frontend/src/pages/secret-manager/integrations/HashicorpVaultConfigurePage/HashicorpVaultConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/HashicorpVaultConfigurePage/HashicorpVaultConfigurePage.tsx @@ -101,7 +101,7 @@ export const HashicorpVaultConfigurePage = () => { secretPath: formData.secretPath }); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/HashicorpVaultConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/HashicorpVaultConfigurePage/route.tsx index 8d8a6c3c0..d4b8cca0c 100644 --- a/frontend/src/pages/secret-manager/integrations/HashicorpVaultConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/HashicorpVaultConfigurePage/route.tsx @@ -11,7 +11,7 @@ const HashicorpVaultConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hashicorp-vault/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/create" )({ component: HashicorpVaultConfigurePage, validateSearch: zodValidator(HashicorpVaultConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/HasuraCloudAuthorizePage/HasuraCloudAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/HasuraCloudAuthorizePage/HasuraCloudAuthorizePage.tsx index 691c2e35c..8c29a0c69 100644 --- a/frontend/src/pages/secret-manager/integrations/HasuraCloudAuthorizePage/HasuraCloudAuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/HasuraCloudAuthorizePage/HasuraCloudAuthorizePage.tsx @@ -43,7 +43,7 @@ export const HasuraCloudAuthorizePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations/hasura-cloud/create", + to: "/projects/secret-management/$projectId/integrations/hasura-cloud/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/HasuraCloudAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/HasuraCloudAuthorizePage/route.tsx index fbd710d4d..41bcfb8c5 100644 --- a/frontend/src/pages/secret-manager/integrations/HasuraCloudAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/HasuraCloudAuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { HasuraCloudAuthorizePage } from "./HasuraCloudAuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hasura-cloud/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/authorize" )({ component: HasuraCloudAuthorizePage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/HasuraCloudConfigurePage/HasuraCloudConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/HasuraCloudConfigurePage/HasuraCloudConfigurePage.tsx index ba6775295..a42451e8e 100644 --- a/frontend/src/pages/secret-manager/integrations/HasuraCloudConfigurePage/HasuraCloudConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/HasuraCloudConfigurePage/HasuraCloudConfigurePage.tsx @@ -70,7 +70,7 @@ export const HasuraCloudConfigurePage = () => { }); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/HasuraCloudConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/HasuraCloudConfigurePage/route.tsx index 6821dda87..ceb4f2f01 100644 --- a/frontend/src/pages/secret-manager/integrations/HasuraCloudConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/HasuraCloudConfigurePage/route.tsx @@ -11,7 +11,7 @@ const HasuraCloudConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hasura-cloud/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/create" )({ component: HasuraCloudConfigurePage, validateSearch: zodValidator(HasuraCloudConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/HerokuConfigurePage/HerokuConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/HerokuConfigurePage/HerokuConfigurePage.tsx index eb4ed81da..c36961ffa 100644 --- a/frontend/src/pages/secret-manager/integrations/HerokuConfigurePage/HerokuConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/HerokuConfigurePage/HerokuConfigurePage.tsx @@ -98,7 +98,7 @@ export const HerokuConfigurePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/HerokuConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/HerokuConfigurePage/route.tsx index 94ff72f9c..4b2a534b2 100644 --- a/frontend/src/pages/secret-manager/integrations/HerokuConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/HerokuConfigurePage/route.tsx @@ -11,7 +11,7 @@ const HerokuConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/heroku/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/create" )({ component: HerokuConfigurePage, validateSearch: zodValidator(HerokuConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/HerokuOauthCallbackPage/route.tsx b/frontend/src/pages/secret-manager/integrations/HerokuOauthCallbackPage/route.tsx index eae7e466c..39e3e464d 100644 --- a/frontend/src/pages/secret-manager/integrations/HerokuOauthCallbackPage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/HerokuOauthCallbackPage/route.tsx @@ -12,7 +12,7 @@ export const HerokuOAuthCallbackPageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/heroku/oauth2/callback" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/oauth2/callback" )({ component: HerokuOAuthCallbackPage, validateSearch: zodValidator(HerokuOAuthCallbackPageQueryParamsSchema), @@ -23,7 +23,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/LaravelForgeAuthorizePage/LaravelForgeAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/LaravelForgeAuthorizePage/LaravelForgeAuthorizePage.tsx index ff04c6521..d67a6ce1d 100644 --- a/frontend/src/pages/secret-manager/integrations/LaravelForgeAuthorizePage/LaravelForgeAuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/LaravelForgeAuthorizePage/LaravelForgeAuthorizePage.tsx @@ -42,7 +42,7 @@ export const LaravelForgeAuthorizePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations/laravel-forge/create", + to: "/projects/secret-management/$projectId/integrations/laravel-forge/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/LaravelForgeAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/LaravelForgeAuthorizePage/route.tsx index 718f5359e..22f19f6d3 100644 --- a/frontend/src/pages/secret-manager/integrations/LaravelForgeAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/LaravelForgeAuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { LaravelForgeAuthorizePage } from "./LaravelForgeAuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/laravel-forge/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/authorize" )({ component: LaravelForgeAuthorizePage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/LaravelForgeConfigurePage/LaravelForgeConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/LaravelForgeConfigurePage/LaravelForgeConfigurePage.tsx index 2e5575d5d..91963e749 100644 --- a/frontend/src/pages/secret-manager/integrations/LaravelForgeConfigurePage/LaravelForgeConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/LaravelForgeConfigurePage/LaravelForgeConfigurePage.tsx @@ -72,7 +72,7 @@ export const LaravelForgeConfigurePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/LaravelForgeConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/LaravelForgeConfigurePage/route.tsx index 6883de4aa..fc5cbd9d8 100644 --- a/frontend/src/pages/secret-manager/integrations/LaravelForgeConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/LaravelForgeConfigurePage/route.tsx @@ -11,7 +11,7 @@ const LaravelForgeConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/laravel-forge/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/create" )({ component: LaravelForgeConfigurePage, validateSearch: zodValidator(LaravelForgeConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/NetlifyConfigurePage/NetlifyConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/NetlifyConfigurePage/NetlifyConfigurePage.tsx index f8d25380b..7450b5cf0 100644 --- a/frontend/src/pages/secret-manager/integrations/NetlifyConfigurePage/NetlifyConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/NetlifyConfigurePage/NetlifyConfigurePage.tsx @@ -79,7 +79,7 @@ export const NetlifyConfigurePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/NetlifyConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/NetlifyConfigurePage/route.tsx index 4fea81a10..0b35f9679 100644 --- a/frontend/src/pages/secret-manager/integrations/NetlifyConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/NetlifyConfigurePage/route.tsx @@ -11,7 +11,7 @@ const NetlifyConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/netlify/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/create" )({ component: NetlifyConfigurePage, validateSearch: zodValidator(NetlifyConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/NetlifyOauthCallbackPage/NetlifyOauthCallbackPage.tsx b/frontend/src/pages/secret-manager/integrations/NetlifyOauthCallbackPage/NetlifyOauthCallbackPage.tsx index 7b30d5f1e..330984622 100644 --- a/frontend/src/pages/secret-manager/integrations/NetlifyOauthCallbackPage/NetlifyOauthCallbackPage.tsx +++ b/frontend/src/pages/secret-manager/integrations/NetlifyOauthCallbackPage/NetlifyOauthCallbackPage.tsx @@ -28,7 +28,7 @@ export const NetlifyOauthCallbackPage = () => { }); navigate({ - to: "/projects/$projectId/secret-manager/integrations/netlify/create", + to: "/projects/secret-management/$projectId/integrations/netlify/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/NetlifyOauthCallbackPage/route.tsx b/frontend/src/pages/secret-manager/integrations/NetlifyOauthCallbackPage/route.tsx index 0fa2e9493..e6d02bea3 100644 --- a/frontend/src/pages/secret-manager/integrations/NetlifyOauthCallbackPage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/NetlifyOauthCallbackPage/route.tsx @@ -12,7 +12,7 @@ export const NetlifyOAuthCallbackPageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/netlify/oauth2/callback" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/oauth2/callback" )({ component: NetlifyOauthCallbackPage, validateSearch: zodValidator(NetlifyOAuthCallbackPageQueryParamsSchema), @@ -23,7 +23,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/NorthflankAuthorizePage/NorthflankAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/NorthflankAuthorizePage/NorthflankAuthorizePage.tsx index 313f8b0af..b203a02dc 100644 --- a/frontend/src/pages/secret-manager/integrations/NorthflankAuthorizePage/NorthflankAuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/NorthflankAuthorizePage/NorthflankAuthorizePage.tsx @@ -33,7 +33,7 @@ export const NorthflankAuthorizePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations/northflank/create", + to: "/projects/secret-management/$projectId/integrations/northflank/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/NorthflankAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/NorthflankAuthorizePage/route.tsx index ea8b31cbc..ae9d8aa94 100644 --- a/frontend/src/pages/secret-manager/integrations/NorthflankAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/NorthflankAuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { NorthflankAuthorizePage } from "./NorthflankAuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/northflank/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/authorize" )({ component: NorthflankAuthorizePage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/NorthflankConfigurePage/NorthflankConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/NorthflankConfigurePage/NorthflankConfigurePage.tsx index 57084d5f9..7f01c32ee 100644 --- a/frontend/src/pages/secret-manager/integrations/NorthflankConfigurePage/NorthflankConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/NorthflankConfigurePage/NorthflankConfigurePage.tsx @@ -93,7 +93,7 @@ export const NorthflankConfigurePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/NorthflankConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/NorthflankConfigurePage/route.tsx index a441bc7f0..0ef3f1f0d 100644 --- a/frontend/src/pages/secret-manager/integrations/NorthflankConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/NorthflankConfigurePage/route.tsx @@ -11,7 +11,7 @@ const NorthflankConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/northflank/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/create" )({ component: NorthflankConfigurePage, validateSearch: zodValidator(NorthflankConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/OctopusDeployAuthorizePage/OctopusDeployAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/OctopusDeployAuthorizePage/OctopusDeployAuthorizePage.tsx index 8e3402a84..789ea3c49 100644 --- a/frontend/src/pages/secret-manager/integrations/OctopusDeployAuthorizePage/OctopusDeployAuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/OctopusDeployAuthorizePage/OctopusDeployAuthorizePage.tsx @@ -38,7 +38,7 @@ export const OctopusDeployAuthorizePage = () => { }); navigate({ - to: "/projects/$projectId/secret-manager/integrations/octopus-deploy/create", + to: "/projects/secret-management/$projectId/integrations/octopus-deploy/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/OctopusDeployAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/OctopusDeployAuthorizePage/route.tsx index fa7b0a9e9..d8daebbd5 100644 --- a/frontend/src/pages/secret-manager/integrations/OctopusDeployAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/OctopusDeployAuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { OctopusDeployAuthorizePage } from "./OctopusDeployAuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/octopus-deploy/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/authorize" )({ component: OctopusDeployAuthorizePage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/OctopusDeployConfigurePage/OctopusDeployConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/OctopusDeployConfigurePage/OctopusDeployConfigurePage.tsx index 2272bc29d..458c4a997 100644 --- a/frontend/src/pages/secret-manager/integrations/OctopusDeployConfigurePage/OctopusDeployConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/OctopusDeployConfigurePage/OctopusDeployConfigurePage.tsx @@ -135,7 +135,7 @@ export const OctopusDeployConfigurePage = () => { text: "Successfully created integration" }); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/OctopusDeployConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/OctopusDeployConfigurePage/route.tsx index 06a4e4e04..6d7669ef6 100644 --- a/frontend/src/pages/secret-manager/integrations/OctopusDeployConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/OctopusDeployConfigurePage/route.tsx @@ -11,7 +11,7 @@ const OctopusDeployConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/octopus-deploy/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/create" )({ component: OctopusDeployConfigurePage, validateSearch: zodValidator(OctopusDeployConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/QoveryAuthorizePage/QoveryAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/QoveryAuthorizePage/QoveryAuthorizePage.tsx index b26f0ad72..607b1962b 100644 --- a/frontend/src/pages/secret-manager/integrations/QoveryAuthorizePage/QoveryAuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/QoveryAuthorizePage/QoveryAuthorizePage.tsx @@ -36,7 +36,7 @@ export const QoveryAuthorizePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations/qovery/create", + to: "/projects/secret-management/$projectId/integrations/qovery/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/QoveryAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/QoveryAuthorizePage/route.tsx index 3cc7e074e..6b484dd62 100644 --- a/frontend/src/pages/secret-manager/integrations/QoveryAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/QoveryAuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { QoveryAuthorizePage } from "./QoveryAuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/qovery/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/authorize" )({ component: QoveryAuthorizePage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/QoveryConfigurePage/QoveryConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/QoveryConfigurePage/QoveryConfigurePage.tsx index f2821300c..bc0f24c90 100644 --- a/frontend/src/pages/secret-manager/integrations/QoveryConfigurePage/QoveryConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/QoveryConfigurePage/QoveryConfigurePage.tsx @@ -176,7 +176,7 @@ export const QoveryConfigurePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/QoveryConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/QoveryConfigurePage/route.tsx index 0a444a6e0..ea5483ade 100644 --- a/frontend/src/pages/secret-manager/integrations/QoveryConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/QoveryConfigurePage/route.tsx @@ -11,7 +11,7 @@ const QoveryConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/qovery/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/create" )({ component: QoveryConfigurePage, validateSearch: zodValidator(QoveryConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/RailwayAuthorizePage/RailwayAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/RailwayAuthorizePage/RailwayAuthorizePage.tsx index 4719bb102..5acc04b1b 100644 --- a/frontend/src/pages/secret-manager/integrations/RailwayAuthorizePage/RailwayAuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/RailwayAuthorizePage/RailwayAuthorizePage.tsx @@ -33,7 +33,7 @@ export const RailwayAuthorizePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations/railway/create", + to: "/projects/secret-management/$projectId/integrations/railway/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/RailwayAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/RailwayAuthorizePage/route.tsx index 78d79a3dd..ced428912 100644 --- a/frontend/src/pages/secret-manager/integrations/RailwayAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/RailwayAuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { RailwayAuthorizePage } from "./RailwayAuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/railway/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/authorize" )({ component: RailwayAuthorizePage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/RailwayConfigurePage/RailwayConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/RailwayConfigurePage/RailwayConfigurePage.tsx index ab2d6a39c..835e59277 100644 --- a/frontend/src/pages/secret-manager/integrations/RailwayConfigurePage/RailwayConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/RailwayConfigurePage/RailwayConfigurePage.tsx @@ -108,7 +108,7 @@ export const RailwayConfigurePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/RailwayConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/RailwayConfigurePage/route.tsx index 8816e2532..2d174fce6 100644 --- a/frontend/src/pages/secret-manager/integrations/RailwayConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/RailwayConfigurePage/route.tsx @@ -11,7 +11,7 @@ const RailwayConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/railway/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/create" )({ component: RailwayConfigurePage, validateSearch: zodValidator(RailwayConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/RenderAuthorizePage/RenderAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/RenderAuthorizePage/RenderAuthorizePage.tsx index a574fe7fc..8be39cb9e 100644 --- a/frontend/src/pages/secret-manager/integrations/RenderAuthorizePage/RenderAuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/RenderAuthorizePage/RenderAuthorizePage.tsx @@ -36,7 +36,7 @@ export const RenderAuthorizePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations/render/create", + to: "/projects/secret-management/$projectId/integrations/render/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/RenderAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/RenderAuthorizePage/route.tsx index 6992c602b..a15091a3e 100644 --- a/frontend/src/pages/secret-manager/integrations/RenderAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/RenderAuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { RenderAuthorizePage } from "./RenderAuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/render/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/authorize" )({ component: RenderAuthorizePage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/RenderConfigurePage/RenderConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/RenderConfigurePage/RenderConfigurePage.tsx index cf1605558..3d156cdac 100644 --- a/frontend/src/pages/secret-manager/integrations/RenderConfigurePage/RenderConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/RenderConfigurePage/RenderConfigurePage.tsx @@ -104,7 +104,7 @@ export const RenderConfigurePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/RenderConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/RenderConfigurePage/route.tsx index 18a6429eb..f29fad07b 100644 --- a/frontend/src/pages/secret-manager/integrations/RenderConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/RenderConfigurePage/route.tsx @@ -11,7 +11,7 @@ const RenderConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/render/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/create" )({ component: RenderConfigurePage, validateSearch: zodValidator(RenderConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/RundeckAuthorizePage/RundeckAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/RundeckAuthorizePage/RundeckAuthorizePage.tsx index 2bf8feac0..f67b22b37 100644 --- a/frontend/src/pages/secret-manager/integrations/RundeckAuthorizePage/RundeckAuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/RundeckAuthorizePage/RundeckAuthorizePage.tsx @@ -48,7 +48,7 @@ export const RundeckAuthorizePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations/rundeck/create", + to: "/projects/secret-management/$projectId/integrations/rundeck/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/RundeckAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/RundeckAuthorizePage/route.tsx index 4fcfde06e..ca0ec2913 100644 --- a/frontend/src/pages/secret-manager/integrations/RundeckAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/RundeckAuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { RundeckAuthorizePage } from "./RundeckAuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/rundeck/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/authorize" )({ component: RundeckAuthorizePage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/RundeckConfigurePage/RundeckConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/RundeckConfigurePage/RundeckConfigurePage.tsx index 43019bb18..7c8dada9f 100644 --- a/frontend/src/pages/secret-manager/integrations/RundeckConfigurePage/RundeckConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/RundeckConfigurePage/RundeckConfigurePage.tsx @@ -71,7 +71,7 @@ export const RundeckConfigurePage = () => { }); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/RundeckConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/RundeckConfigurePage/route.tsx index 32aaede54..0a46bdc35 100644 --- a/frontend/src/pages/secret-manager/integrations/RundeckConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/RundeckConfigurePage/route.tsx @@ -11,7 +11,7 @@ const RundeskConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/rundeck/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/create" )({ component: RundeckConfigurePage, validateSearch: zodValidator(RundeskConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/SelectIntegrationAuthPage/SelectIntegrationAuthPage.tsx b/frontend/src/pages/secret-manager/integrations/SelectIntegrationAuthPage/SelectIntegrationAuthPage.tsx index 67cceda71..d06ab24fb 100644 --- a/frontend/src/pages/secret-manager/integrations/SelectIntegrationAuthPage/SelectIntegrationAuthPage.tsx +++ b/frontend/src/pages/secret-manager/integrations/SelectIntegrationAuthPage/SelectIntegrationAuthPage.tsx @@ -119,7 +119,7 @@ export const SelectIntegrationAuthPage = () => { if (integrationSlug === "github") { if (integrationAuth.projectId === currentWorkspace?.id) { navigate({ - to: "/projects/$projectId/secret-manager/integrations/github/create", + to: "/projects/secret-management/$projectId/integrations/github/create", params: { projectId: currentWorkspace.id }, @@ -135,7 +135,7 @@ export const SelectIntegrationAuthPage = () => { }); navigate({ - to: "/projects/$projectId/secret-manager/integrations/github/create", + to: "/projects/secret-management/$projectId/integrations/github/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/SelectIntegrationAuthPage/route.tsx b/frontend/src/pages/secret-manager/integrations/SelectIntegrationAuthPage/route.tsx index 6cd1fa6a5..0bba2b502 100644 --- a/frontend/src/pages/secret-manager/integrations/SelectIntegrationAuthPage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/SelectIntegrationAuthPage/route.tsx @@ -11,7 +11,7 @@ const SelectIntegrationAuthPageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/select-integration-auth" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/select-integration-auth" )({ component: SelectIntegrationAuthPage, validateSearch: zodValidator(SelectIntegrationAuthPageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/SupabaseAuthorizePage/SupabaseAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/SupabaseAuthorizePage/SupabaseAuthorizePage.tsx index c411df91f..5ec969e11 100644 --- a/frontend/src/pages/secret-manager/integrations/SupabaseAuthorizePage/SupabaseAuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/SupabaseAuthorizePage/SupabaseAuthorizePage.tsx @@ -33,7 +33,7 @@ export const SupabaseAuthorizePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations/supabase/create", + to: "/projects/secret-management/$projectId/integrations/supabase/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/SupabaseAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/SupabaseAuthorizePage/route.tsx index 37ddfed8c..398760948 100644 --- a/frontend/src/pages/secret-manager/integrations/SupabaseAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/SupabaseAuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { SupabaseAuthorizePage } from "./SupabaseAuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/supabase/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/authorize" )({ component: SupabaseAuthorizePage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/SupabaseConfigurePage/SupabaseConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/SupabaseConfigurePage/SupabaseConfigurePage.tsx index fb18a59db..333c61a8e 100644 --- a/frontend/src/pages/secret-manager/integrations/SupabaseConfigurePage/SupabaseConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/SupabaseConfigurePage/SupabaseConfigurePage.tsx @@ -71,7 +71,7 @@ export const SupabaseConfigurePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/SupabaseConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/SupabaseConfigurePage/route.tsx index c8334f197..007318665 100644 --- a/frontend/src/pages/secret-manager/integrations/SupabaseConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/SupabaseConfigurePage/route.tsx @@ -11,7 +11,7 @@ const SupabaseConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/supabase/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/create" )({ component: SupabaseConfigurePage, validateSearch: zodValidator(SupabaseConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/TeamcityAuthorizePage/TeamcityAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/TeamcityAuthorizePage/TeamcityAuthorizePage.tsx index 881224392..4698fac59 100644 --- a/frontend/src/pages/secret-manager/integrations/TeamcityAuthorizePage/TeamcityAuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/TeamcityAuthorizePage/TeamcityAuthorizePage.tsx @@ -46,7 +46,7 @@ export const TeamcityAuthorizePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations/teamcity/create", + to: "/projects/secret-management/$projectId/integrations/teamcity/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/TeamcityAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/TeamcityAuthorizePage/route.tsx index b18e75bfe..32d92f718 100644 --- a/frontend/src/pages/secret-manager/integrations/TeamcityAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/TeamcityAuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { TeamcityAuthorizePage } from "./TeamcityAuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/teamcity/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/authorize" )({ component: TeamcityAuthorizePage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/TeamcityConfigurePage/TeamcityConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/TeamcityConfigurePage/TeamcityConfigurePage.tsx index 30b54636f..9291d0d5f 100644 --- a/frontend/src/pages/secret-manager/integrations/TeamcityConfigurePage/TeamcityConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/TeamcityConfigurePage/TeamcityConfigurePage.tsx @@ -90,7 +90,7 @@ export const TeamcityConfigurePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/TeamcityConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/TeamcityConfigurePage/route.tsx index 1214e0846..105395616 100644 --- a/frontend/src/pages/secret-manager/integrations/TeamcityConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/TeamcityConfigurePage/route.tsx @@ -11,7 +11,7 @@ const TeamcityConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/teamcity/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/create" )({ component: TeamcityConfigurePage, validateSearch: zodValidator(TeamcityConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/TerraformCloudAuthorizePage/TerraformCloudAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/TerraformCloudAuthorizePage/TerraformCloudAuthorizePage.tsx index 34fa74f79..eac1fa0c0 100644 --- a/frontend/src/pages/secret-manager/integrations/TerraformCloudAuthorizePage/TerraformCloudAuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/TerraformCloudAuthorizePage/TerraformCloudAuthorizePage.tsx @@ -46,7 +46,7 @@ export const TerraformCloudAuthorizePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations/terraform-cloud/create", + to: "/projects/secret-management/$projectId/integrations/terraform-cloud/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/TerraformCloudAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/TerraformCloudAuthorizePage/route.tsx index 7ec3ce32a..9bb65026f 100644 --- a/frontend/src/pages/secret-manager/integrations/TerraformCloudAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/TerraformCloudAuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { TerraformCloudAuthorizePage } from "./TerraformCloudAuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/terraform-cloud/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/authorize" )({ component: TerraformCloudAuthorizePage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/TerraformCloudConfigurePage/TerraformCloudConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/TerraformCloudConfigurePage/TerraformCloudConfigurePage.tsx index 1151ad0e3..a2d73feca 100644 --- a/frontend/src/pages/secret-manager/integrations/TerraformCloudConfigurePage/TerraformCloudConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/TerraformCloudConfigurePage/TerraformCloudConfigurePage.tsx @@ -105,7 +105,7 @@ export const TerraformCloudConfigurePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/TerraformCloudConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/TerraformCloudConfigurePage/route.tsx index 813903492..0b1f47c5d 100644 --- a/frontend/src/pages/secret-manager/integrations/TerraformCloudConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/TerraformCloudConfigurePage/route.tsx @@ -11,7 +11,7 @@ const TerraformCloudConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/terraform-cloud/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/create" )({ component: TerraformCloudConfigurePage, validateSearch: zodValidator(TerraformCloudConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/TravisCIAuthorizePage/TravisCIAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/TravisCIAuthorizePage/TravisCIAuthorizePage.tsx index 396e2f48f..3323aed7d 100644 --- a/frontend/src/pages/secret-manager/integrations/TravisCIAuthorizePage/TravisCIAuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/TravisCIAuthorizePage/TravisCIAuthorizePage.tsx @@ -33,7 +33,7 @@ export const TravisCIAuthorizePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations/travisci/create", + to: "/projects/secret-management/$projectId/integrations/travisci/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/TravisCIAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/TravisCIAuthorizePage/route.tsx index 7afe76709..d26c0aecc 100644 --- a/frontend/src/pages/secret-manager/integrations/TravisCIAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/TravisCIAuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { TravisCIAuthorizePage } from "./TravisCIAuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/travisci/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/authorize" )({ component: TravisCIAuthorizePage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/TravisCIConfigurePage/TravisCIConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/TravisCIConfigurePage/TravisCIConfigurePage.tsx index e4bb91e84..66c3a8022 100644 --- a/frontend/src/pages/secret-manager/integrations/TravisCIConfigurePage/TravisCIConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/TravisCIConfigurePage/TravisCIConfigurePage.tsx @@ -72,7 +72,7 @@ export const TravisCIConfigurePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/TravisCIConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/TravisCIConfigurePage/route.tsx index 32747a540..8bab87913 100644 --- a/frontend/src/pages/secret-manager/integrations/TravisCIConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/TravisCIConfigurePage/route.tsx @@ -11,7 +11,7 @@ const TravisCIConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/travisci/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/create" )({ component: TravisCIConfigurePage, validateSearch: zodValidator(TravisCIConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/VercelConfigurePage/VercelConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/VercelConfigurePage/VercelConfigurePage.tsx index 34f88d31a..25c209f09 100644 --- a/frontend/src/pages/secret-manager/integrations/VercelConfigurePage/VercelConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/VercelConfigurePage/VercelConfigurePage.tsx @@ -132,7 +132,7 @@ export const VercelConfigurePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/VercelConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/VercelConfigurePage/route.tsx index 18f165b1d..892e50cda 100644 --- a/frontend/src/pages/secret-manager/integrations/VercelConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/VercelConfigurePage/route.tsx @@ -11,7 +11,7 @@ const VercelConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/vercel/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/create" )({ component: VercelConfigurePage, validateSearch: zodValidator(VercelConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/VercelOauthCallbackPage/VercelOauthCallbackPage.tsx b/frontend/src/pages/secret-manager/integrations/VercelOauthCallbackPage/VercelOauthCallbackPage.tsx index b6257ac68..02fb22eab 100644 --- a/frontend/src/pages/secret-manager/integrations/VercelOauthCallbackPage/VercelOauthCallbackPage.tsx +++ b/frontend/src/pages/secret-manager/integrations/VercelOauthCallbackPage/VercelOauthCallbackPage.tsx @@ -28,7 +28,7 @@ export const VercelOauthCallbackPage = () => { }); navigate({ - to: "/projects/$projectId/secret-manager/integrations/vercel/create", + to: "/projects/secret-management/$projectId/integrations/vercel/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/VercelOauthCallbackPage/route.tsx b/frontend/src/pages/secret-manager/integrations/VercelOauthCallbackPage/route.tsx index f1f434722..c2a4c11c1 100644 --- a/frontend/src/pages/secret-manager/integrations/VercelOauthCallbackPage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/VercelOauthCallbackPage/route.tsx @@ -12,7 +12,7 @@ export const VercelOAuthCallbackPageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/vercel/oauth2/callback" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/oauth2/callback" )({ component: VercelOauthCallbackPage, validateSearch: zodValidator(VercelOAuthCallbackPageQueryParamsSchema), @@ -23,7 +23,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/WindmillAuthorizePage/WindmillAuthorizePage.tsx b/frontend/src/pages/secret-manager/integrations/WindmillAuthorizePage/WindmillAuthorizePage.tsx index d71f5da04..36e791e56 100644 --- a/frontend/src/pages/secret-manager/integrations/WindmillAuthorizePage/WindmillAuthorizePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/WindmillAuthorizePage/WindmillAuthorizePage.tsx @@ -77,7 +77,7 @@ export const WindmillAuthorizePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations/windmill/create", + to: "/projects/secret-management/$projectId/integrations/windmill/create", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/WindmillAuthorizePage/route.tsx b/frontend/src/pages/secret-manager/integrations/WindmillAuthorizePage/route.tsx index 191116051..6714e0e41 100644 --- a/frontend/src/pages/secret-manager/integrations/WindmillAuthorizePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/WindmillAuthorizePage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { WindmillAuthorizePage } from "./WindmillAuthorizePage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/windmill/authorize" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/authorize" )({ component: WindmillAuthorizePage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/WindmillConfigurePage/WindmillConfigurePage.tsx b/frontend/src/pages/secret-manager/integrations/WindmillConfigurePage/WindmillConfigurePage.tsx index c0be6ef6d..17929b2a3 100644 --- a/frontend/src/pages/secret-manager/integrations/WindmillConfigurePage/WindmillConfigurePage.tsx +++ b/frontend/src/pages/secret-manager/integrations/WindmillConfigurePage/WindmillConfigurePage.tsx @@ -74,7 +74,7 @@ export const WindmillConfigurePage = () => { setIsLoading(false); navigate({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-manager/integrations/WindmillConfigurePage/route.tsx b/frontend/src/pages/secret-manager/integrations/WindmillConfigurePage/route.tsx index 2f6184ac6..03ab5da6a 100644 --- a/frontend/src/pages/secret-manager/integrations/WindmillConfigurePage/route.tsx +++ b/frontend/src/pages/secret-manager/integrations/WindmillConfigurePage/route.tsx @@ -11,7 +11,7 @@ const WindmillConfigurePageQueryParamsSchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/windmill/create" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/create" )({ component: WindmillConfigurePage, validateSearch: zodValidator(WindmillConfigurePageQueryParamsSchema), @@ -22,7 +22,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/projects/$projectId/secret-manager/integrations", + to: "/projects/secret-management/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.NativeIntegrations diff --git a/frontend/src/pages/secret-manager/integrations/route-azure-app-configurations-oauth-redirect.tsx b/frontend/src/pages/secret-manager/integrations/route-azure-app-configurations-oauth-redirect.tsx index d23b9c6f3..f26135eae 100644 --- a/frontend/src/pages/secret-manager/integrations/route-azure-app-configurations-oauth-redirect.tsx +++ b/frontend/src/pages/secret-manager/integrations/route-azure-app-configurations-oauth-redirect.tsx @@ -7,7 +7,7 @@ import { localStorageService } from "@app/helpers/localStorage"; import { AzureAppConfigurationOauthCallbackPageQueryParamsSchema } from "./AzureAppConfigurationOauthCallbackPage/route"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/azure-app-configuration/oauth2/callback" + "/_authenticate/_inject-org-details/_org-layout/integrations/azure-app-configuration/oauth2/callback" )({ validateSearch: zodValidator(AzureAppConfigurationOauthCallbackPageQueryParamsSchema), beforeLoad: ({ search }) => { @@ -21,7 +21,7 @@ export const Route = createFileRoute( throw redirect({ to: "/organization/projects" }); } throw redirect({ - to: "/projects/$projectId/secret-manager/integrations/azure-app-configuration/oauth2/callback", + to: "/projects/secret-management/$projectId/integrations/azure-app-configuration/oauth2/callback", params: { projectId }, search }); diff --git a/frontend/src/pages/secret-manager/integrations/route-azure-key-vault-oauth-redirect.tsx b/frontend/src/pages/secret-manager/integrations/route-azure-key-vault-oauth-redirect.tsx index 441209c02..614519da3 100644 --- a/frontend/src/pages/secret-manager/integrations/route-azure-key-vault-oauth-redirect.tsx +++ b/frontend/src/pages/secret-manager/integrations/route-azure-key-vault-oauth-redirect.tsx @@ -7,7 +7,7 @@ import { localStorageService } from "@app/helpers/localStorage"; import { AzureKeyVaultOauthCallbackQueryParamsSchema } from "./AzureKeyVaultOauthCallbackPage/route"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/azure-key-vault/oauth2/callback" + "/_authenticate/_inject-org-details/_org-layout/integrations/azure-key-vault/oauth2/callback" )({ validateSearch: zodValidator(AzureKeyVaultOauthCallbackQueryParamsSchema), beforeLoad: ({ search }) => { @@ -21,7 +21,7 @@ export const Route = createFileRoute( throw redirect({ to: "/organization/projects" }); } throw redirect({ - to: "/projects/$projectId/secret-manager/integrations/azure-key-vault/oauth2/callback", + to: "/projects/secret-management/$projectId/integrations/azure-key-vault/oauth2/callback", params: { projectId }, search }); diff --git a/frontend/src/pages/secret-manager/integrations/route-bitbucket-oauth-redirect.tsx b/frontend/src/pages/secret-manager/integrations/route-bitbucket-oauth-redirect.tsx index 77aa52950..b935caf55 100644 --- a/frontend/src/pages/secret-manager/integrations/route-bitbucket-oauth-redirect.tsx +++ b/frontend/src/pages/secret-manager/integrations/route-bitbucket-oauth-redirect.tsx @@ -7,7 +7,7 @@ import { localStorageService } from "@app/helpers/localStorage"; import { BitbucketOauthCallbackQueryParamsSchema } from "./BitbucketOauthCallbackPage/route"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/bitbucket/oauth2/callback" + "/_authenticate/_inject-org-details/_org-layout/integrations/bitbucket/oauth2/callback" )({ validateSearch: zodValidator(BitbucketOauthCallbackQueryParamsSchema), beforeLoad: ({ search }) => { @@ -21,7 +21,7 @@ export const Route = createFileRoute( throw redirect({ to: "/organization/projects" }); } throw redirect({ - to: "/projects/$projectId/secret-manager/integrations/bitbucket/oauth2/callback", + to: "/projects/secret-management/$projectId/integrations/bitbucket/oauth2/callback", params: { projectId }, search }); diff --git a/frontend/src/pages/secret-manager/integrations/route-gcp-oauth-redirect.tsx b/frontend/src/pages/secret-manager/integrations/route-gcp-oauth-redirect.tsx index bdd09427a..21f528f01 100644 --- a/frontend/src/pages/secret-manager/integrations/route-gcp-oauth-redirect.tsx +++ b/frontend/src/pages/secret-manager/integrations/route-gcp-oauth-redirect.tsx @@ -7,7 +7,7 @@ import { localStorageService } from "@app/helpers/localStorage"; import { GcpSecretManagerOAuthCallbackPageQueryParamsSchema } from "./GcpSecretManagerOauthCallbackPage/route"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/gcp-secret-manager/oauth2/callback" + "/_authenticate/_inject-org-details/_org-layout/integrations/gcp-secret-manager/oauth2/callback" )({ validateSearch: zodValidator(GcpSecretManagerOAuthCallbackPageQueryParamsSchema), beforeLoad: ({ search }) => { @@ -21,7 +21,7 @@ export const Route = createFileRoute( throw redirect({ to: "/organization/projects" }); } throw redirect({ - to: "/projects/$projectId/secret-manager/integrations/gcp-secret-manager/oauth2/callback", + to: "/projects/secret-management/$projectId/integrations/gcp-secret-manager/oauth2/callback", params: { projectId }, search }); diff --git a/frontend/src/pages/secret-manager/integrations/route-github-oauth-redirect.tsx b/frontend/src/pages/secret-manager/integrations/route-github-oauth-redirect.tsx index 4f5943edb..3f2e922c1 100644 --- a/frontend/src/pages/secret-manager/integrations/route-github-oauth-redirect.tsx +++ b/frontend/src/pages/secret-manager/integrations/route-github-oauth-redirect.tsx @@ -7,7 +7,7 @@ import { localStorageService } from "@app/helpers/localStorage"; import { GithubOAuthCallbackPageQueryParamsSchema } from "./GithubOauthCallbackPage/route"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/github/oauth2/callback" + "/_authenticate/_inject-org-details/_org-layout/integrations/github/oauth2/callback" )({ validateSearch: zodValidator(GithubOAuthCallbackPageQueryParamsSchema), beforeLoad: ({ search }) => { @@ -21,7 +21,7 @@ export const Route = createFileRoute( throw redirect({ to: "/organization/projects" }); } throw redirect({ - to: "/projects/$projectId/secret-manager/integrations/github/oauth2/callback", + to: "/projects/secret-management/$projectId/integrations/github/oauth2/callback", params: { projectId }, search }); diff --git a/frontend/src/pages/secret-manager/integrations/route-gitlab-oauth-redirect.tsx b/frontend/src/pages/secret-manager/integrations/route-gitlab-oauth-redirect.tsx index d52f5d61a..f88e4c8a7 100644 --- a/frontend/src/pages/secret-manager/integrations/route-gitlab-oauth-redirect.tsx +++ b/frontend/src/pages/secret-manager/integrations/route-gitlab-oauth-redirect.tsx @@ -7,7 +7,7 @@ import { localStorageService } from "@app/helpers/localStorage"; import { GitlabOAuthCallbackPageQueryParamsSchema } from "./GitlabOauthCallbackPage/route"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/gitlab/oauth2/callback" + "/_authenticate/_inject-org-details/_org-layout/integrations/gitlab/oauth2/callback" )({ validateSearch: zodValidator(GitlabOAuthCallbackPageQueryParamsSchema), beforeLoad: ({ search }) => { @@ -21,7 +21,7 @@ export const Route = createFileRoute( throw redirect({ to: "/organization/projects" }); } throw redirect({ - to: "/projects/$projectId/secret-manager/integrations/gitlab/oauth2/callback", + to: "/projects/secret-management/$projectId/integrations/gitlab/oauth2/callback", params: { projectId }, search }); diff --git a/frontend/src/pages/secret-manager/integrations/route-heroku-oauth-redirect.tsx b/frontend/src/pages/secret-manager/integrations/route-heroku-oauth-redirect.tsx index b12f6ea61..881d35a75 100644 --- a/frontend/src/pages/secret-manager/integrations/route-heroku-oauth-redirect.tsx +++ b/frontend/src/pages/secret-manager/integrations/route-heroku-oauth-redirect.tsx @@ -7,7 +7,7 @@ import { localStorageService } from "@app/helpers/localStorage"; import { HerokuOAuthCallbackPageQueryParamsSchema } from "./HerokuOauthCallbackPage/route"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/heroku/oauth2/callback" + "/_authenticate/_inject-org-details/_org-layout/integrations/heroku/oauth2/callback" )({ validateSearch: zodValidator(HerokuOAuthCallbackPageQueryParamsSchema), beforeLoad: ({ search }) => { @@ -21,7 +21,7 @@ export const Route = createFileRoute( throw redirect({ to: "/organization/projects" }); } throw redirect({ - to: "/projects/$projectId/secret-manager/integrations/heroku/oauth2/callback", + to: "/projects/secret-management/$projectId/integrations/heroku/oauth2/callback", params: { projectId }, search }); diff --git a/frontend/src/pages/secret-manager/integrations/route-netlify-oauth-redirect.tsx b/frontend/src/pages/secret-manager/integrations/route-netlify-oauth-redirect.tsx index 396ba24c6..586d0b840 100644 --- a/frontend/src/pages/secret-manager/integrations/route-netlify-oauth-redirect.tsx +++ b/frontend/src/pages/secret-manager/integrations/route-netlify-oauth-redirect.tsx @@ -7,7 +7,7 @@ import { localStorageService } from "@app/helpers/localStorage"; import { NetlifyOAuthCallbackPageQueryParamsSchema } from "./NetlifyOauthCallbackPage/route"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/netlify/oauth2/callback" + "/_authenticate/_inject-org-details/_org-layout/integrations/netlify/oauth2/callback" )({ validateSearch: zodValidator(NetlifyOAuthCallbackPageQueryParamsSchema), beforeLoad: ({ search }) => { @@ -21,7 +21,7 @@ export const Route = createFileRoute( throw redirect({ to: "/organization/projects" }); } throw redirect({ - to: "/projects/$projectId/secret-manager/integrations/netlify/oauth2/callback", + to: "/projects/secret-management/$projectId/integrations/netlify/oauth2/callback", params: { projectId }, search }); diff --git a/frontend/src/pages/secret-manager/integrations/route-vercel-oauth-redirect.tsx b/frontend/src/pages/secret-manager/integrations/route-vercel-oauth-redirect.tsx index 8a0a7874f..b7bcbb52b 100644 --- a/frontend/src/pages/secret-manager/integrations/route-vercel-oauth-redirect.tsx +++ b/frontend/src/pages/secret-manager/integrations/route-vercel-oauth-redirect.tsx @@ -7,7 +7,7 @@ import { localStorageService } from "@app/helpers/localStorage"; import { VercelOAuthCallbackPageQueryParamsSchema } from "./VercelOauthCallbackPage/route"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/vercel/oauth2/callback" + "/_authenticate/_inject-org-details/_org-layout/integrations/vercel/oauth2/callback" )({ validateSearch: zodValidator(VercelOAuthCallbackPageQueryParamsSchema), beforeLoad: ({ search }) => { @@ -21,7 +21,7 @@ export const Route = createFileRoute( throw redirect({ to: "/organization/projects" }); } throw redirect({ - to: "/projects/$projectId/secret-manager/integrations/vercel/oauth2/callback", + to: "/projects/secret-management/$projectId/integrations/vercel/oauth2/callback", params: { projectId }, search }); diff --git a/frontend/src/pages/secret-manager/layout.tsx b/frontend/src/pages/secret-manager/layout.tsx index 889e0c98f..73c3278d0 100644 --- a/frontend/src/pages/secret-manager/layout.tsx +++ b/frontend/src/pages/secret-manager/layout.tsx @@ -1,9 +1,38 @@ import { createFileRoute } from "@tanstack/react-router"; +import { BreadcrumbTypes } from "@app/components/v2"; +import { workspaceKeys } from "@app/hooks/api"; +import { fetchUserProjectPermissions, roleQueryKeys } from "@app/hooks/api/roles/queries"; +import { fetchWorkspaceById } from "@app/hooks/api/workspace/queries"; +import { ProjectSelect } from "@app/layouts/ProjectLayout/components/ProjectSelect"; import { SecretManagerLayout } from "@app/layouts/SecretManagerLayout"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout" )({ - component: SecretManagerLayout + component: SecretManagerLayout, + + beforeLoad: async ({ params, context }) => { + const project = await context.queryClient.ensureQueryData({ + queryKey: workspaceKeys.getWorkspaceById(params.projectId), + queryFn: () => fetchWorkspaceById(params.projectId) + }); + + await context.queryClient.ensureQueryData({ + queryKey: roleQueryKeys.getUserProjectPermissions({ + workspaceId: params.projectId + }), + queryFn: () => fetchUserProjectPermissions({ workspaceId: params.projectId }) + }); + + return { + project, + breadcrumbs: [ + { + type: BreadcrumbTypes.Component, + component: ProjectSelect + } + ] + }; + } }); diff --git a/frontend/src/pages/secret-manager/redirects/redirect-approval-page.tsx b/frontend/src/pages/secret-manager/redirects/redirect-approval-page.tsx index 8fe2c51cf..e871e379a 100644 --- a/frontend/src/pages/secret-manager/redirects/redirect-approval-page.tsx +++ b/frontend/src/pages/secret-manager/redirects/redirect-approval-page.tsx @@ -6,7 +6,7 @@ export const Route = createFileRoute( )({ beforeLoad: ({ params, search }) => { throw redirect({ - to: "/projects/$projectId/secret-manager/approval", + to: "/projects/secret-management/$projectId/approval", params, search }); diff --git a/frontend/src/pages/secret-scanning/SecretScanningDataSourceByIdPage/SecretScanningDataSourceByIdPage.tsx b/frontend/src/pages/secret-scanning/SecretScanningDataSourceByIdPage/SecretScanningDataSourceByIdPage.tsx index bd68c268a..c706b2fd4 100644 --- a/frontend/src/pages/secret-scanning/SecretScanningDataSourceByIdPage/SecretScanningDataSourceByIdPage.tsx +++ b/frontend/src/pages/secret-scanning/SecretScanningDataSourceByIdPage/SecretScanningDataSourceByIdPage.tsx @@ -63,7 +63,7 @@ const PageContent = () => { leftIcon={} onClick={() => { navigate({ - to: "/projects/$projectId/secret-scanning/data-sources", + to: "/projects/secret-scanning/$projectId/data-sources", params: { projectId } diff --git a/frontend/src/pages/secret-scanning/SecretScanningDataSourceByIdPage/components/SecretScanningResourceRow.tsx b/frontend/src/pages/secret-scanning/SecretScanningDataSourceByIdPage/components/SecretScanningResourceRow.tsx index ca63527e1..4534056af 100644 --- a/frontend/src/pages/secret-scanning/SecretScanningDataSourceByIdPage/components/SecretScanningResourceRow.tsx +++ b/frontend/src/pages/secret-scanning/SecretScanningDataSourceByIdPage/components/SecretScanningResourceRow.tsx @@ -135,7 +135,7 @@ export const SecretScanningResourceRow = ({ resource, dataSource }: Props) => { navigate({ - to: "/projects/$projectId/secret-scanning/findings", + to: "/projects/secret-scanning/$projectId/findings", params: { projectId: dataSource.projectId }, diff --git a/frontend/src/pages/secret-scanning/SecretScanningDataSourceByIdPage/components/SecretScanningScanRow.tsx b/frontend/src/pages/secret-scanning/SecretScanningDataSourceByIdPage/components/SecretScanningScanRow.tsx index f5dcb74f9..6dc7ceb35 100644 --- a/frontend/src/pages/secret-scanning/SecretScanningDataSourceByIdPage/components/SecretScanningScanRow.tsx +++ b/frontend/src/pages/secret-scanning/SecretScanningDataSourceByIdPage/components/SecretScanningScanRow.tsx @@ -95,7 +95,7 @@ export const SecretScanningScanRow = ({ scan }: Props) => { navigate({ - to: "/projects/$projectId/secret-scanning/findings", + to: "/projects/secret-scanning/$projectId/findings", params: { projectId: currentWorkspace.id }, diff --git a/frontend/src/pages/secret-scanning/SecretScanningDataSourceByIdPage/route.tsx b/frontend/src/pages/secret-scanning/SecretScanningDataSourceByIdPage/route.tsx index 77c61ac05..21768e3b3 100644 --- a/frontend/src/pages/secret-scanning/SecretScanningDataSourceByIdPage/route.tsx +++ b/frontend/src/pages/secret-scanning/SecretScanningDataSourceByIdPage/route.tsx @@ -3,7 +3,7 @@ import { createFileRoute, linkOptions } from "@tanstack/react-router"; import { SecretScanningDataSourceByIdPage } from "./SecretScanningDataSourceByIdPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/data-sources/$type/$dataSourceId" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/$type/$dataSourceId" )({ component: SecretScanningDataSourceByIdPage, beforeLoad: ({ context, params }) => { @@ -13,7 +13,7 @@ export const Route = createFileRoute( { label: "Data Sources", link: linkOptions({ - to: "/projects/$projectId/secret-scanning/data-sources", + to: "/projects/secret-scanning/$projectId/data-sources", params }) }, diff --git a/frontend/src/pages/secret-scanning/SecretScanningDataSourcesPage/components/SecretScanningDataSourceRow.tsx b/frontend/src/pages/secret-scanning/SecretScanningDataSourcesPage/components/SecretScanningDataSourceRow.tsx index d72aa135d..3dbea9003 100644 --- a/frontend/src/pages/secret-scanning/SecretScanningDataSourcesPage/components/SecretScanningDataSourceRow.tsx +++ b/frontend/src/pages/secret-scanning/SecretScanningDataSourcesPage/components/SecretScanningDataSourceRow.tsx @@ -156,7 +156,7 @@ export const SecretScanningDataSourceRow = ({ onClick={(e) => { e.stopPropagation(); navigate({ - to: "/projects/$projectId/secret-scanning/findings", + to: "/projects/secret-scanning/$projectId/findings", params: { projectId }, diff --git a/frontend/src/pages/secret-scanning/SecretScanningDataSourcesPage/route.tsx b/frontend/src/pages/secret-scanning/SecretScanningDataSourcesPage/route.tsx index be85dc257..b13c99db7 100644 --- a/frontend/src/pages/secret-scanning/SecretScanningDataSourcesPage/route.tsx +++ b/frontend/src/pages/secret-scanning/SecretScanningDataSourcesPage/route.tsx @@ -3,7 +3,7 @@ import { createFileRoute } from "@tanstack/react-router"; import { SecretScanningDataSourcesPage } from "./SecretScanningDataSourcesPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/data-sources/" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/" )({ component: SecretScanningDataSourcesPage, beforeLoad: ({ context }) => { diff --git a/frontend/src/pages/secret-scanning/SecretScanningFindingsPage/route.tsx b/frontend/src/pages/secret-scanning/SecretScanningFindingsPage/route.tsx index 6bb622c99..bfed1fcaf 100644 --- a/frontend/src/pages/secret-scanning/SecretScanningFindingsPage/route.tsx +++ b/frontend/src/pages/secret-scanning/SecretScanningFindingsPage/route.tsx @@ -7,7 +7,7 @@ import { SecretScanningFindingStatus } from "@app/hooks/api/secretScanningV2"; import { SecretScanningFindingsPage } from "./SecretScanningFindingsPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/findings" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/findings" )({ validateSearch: zodValidator( z.object({ diff --git a/frontend/src/pages/secret-scanning/SettingsPage/SettingsPage.tsx b/frontend/src/pages/secret-scanning/SettingsPage/SettingsPage.tsx index 333479984..78df3da54 100644 --- a/frontend/src/pages/secret-scanning/SettingsPage/SettingsPage.tsx +++ b/frontend/src/pages/secret-scanning/SettingsPage/SettingsPage.tsx @@ -10,6 +10,7 @@ import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2"; import { ProjectPermissionSub, useSubscription } from "@app/context"; import { ProjectPermissionSecretScanningConfigActions } from "@app/context/ProjectPermissionContext/types"; import { usePopUp } from "@app/hooks"; +import { ProjectGeneralTab } from "@app/pages/project/SettingsPage/components/ProjectGeneralTab"; import { ProjectScanningConfigTab } from "./components/ProjectScanningConfigTab"; @@ -62,8 +63,12 @@ export const SettingsPage = () => { General + Scanning Settings + + + { diff --git a/frontend/src/pages/secret-scanning/layout.tsx b/frontend/src/pages/secret-scanning/layout.tsx index 24997ca42..38899a233 100644 --- a/frontend/src/pages/secret-scanning/layout.tsx +++ b/frontend/src/pages/secret-scanning/layout.tsx @@ -1,9 +1,37 @@ import { createFileRoute } from "@tanstack/react-router"; +import { BreadcrumbTypes } from "@app/components/v2"; +import { workspaceKeys } from "@app/hooks/api"; +import { fetchUserProjectPermissions, roleQueryKeys } from "@app/hooks/api/roles/queries"; +import { fetchWorkspaceById } from "@app/hooks/api/workspace/queries"; +import { ProjectSelect } from "@app/layouts/ProjectLayout/components/ProjectSelect"; import { SecretScanningLayout } from "@app/layouts/SecretScanningLayout"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout" )({ - component: SecretScanningLayout + component: SecretScanningLayout, + beforeLoad: async ({ params, context }) => { + const project = await context.queryClient.ensureQueryData({ + queryKey: workspaceKeys.getWorkspaceById(params.projectId), + queryFn: () => fetchWorkspaceById(params.projectId) + }); + + await context.queryClient.ensureQueryData({ + queryKey: roleQueryKeys.getUserProjectPermissions({ + workspaceId: params.projectId + }), + queryFn: () => fetchUserProjectPermissions({ workspaceId: params.projectId }) + }); + + return { + project, + breadcrumbs: [ + { + type: BreadcrumbTypes.Component, + component: ProjectSelect + } + ] + }; + } }); diff --git a/frontend/src/pages/ssh/SettingsPage/SettingsPage.tsx b/frontend/src/pages/ssh/SettingsPage/SettingsPage.tsx index 7a7b612df..841bb119f 100644 --- a/frontend/src/pages/ssh/SettingsPage/SettingsPage.tsx +++ b/frontend/src/pages/ssh/SettingsPage/SettingsPage.tsx @@ -4,6 +4,7 @@ import { useTranslation } from "react-i18next"; import { ProjectPermissionCan } from "@app/components/permissions"; import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context"; +import { ProjectGeneralTab } from "@app/pages/project/SettingsPage/components/ProjectGeneralTab"; import { ProjectSshTab } from "./components/ProjectSshTab"; @@ -20,8 +21,12 @@ export const SettingsPage = () => { General + SSH Settings + + + { diff --git a/frontend/src/pages/ssh/SshCaByIDPage/SshCaByIDPage.tsx b/frontend/src/pages/ssh/SshCaByIDPage/SshCaByIDPage.tsx index 3a41ec084..8bed6e647 100644 --- a/frontend/src/pages/ssh/SshCaByIDPage/SshCaByIDPage.tsx +++ b/frontend/src/pages/ssh/SshCaByIDPage/SshCaByIDPage.tsx @@ -17,7 +17,6 @@ import { import { ROUTE_PATHS } from "@app/const/routes"; import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context"; import { useDeleteSshCa, useGetSshCaById } from "@app/hooks/api"; -import { ProjectType } from "@app/hooks/api/workspace/types"; import { usePopUp } from "@app/hooks/usePopUp"; import { SshCaModal } from "../SshCasPage/components/SshCaModal"; @@ -53,7 +52,7 @@ const Page = () => { handlePopUpClose("deleteSshCa"); navigate({ - to: `/projects/$projectId/${ProjectType.SSH}/overview` as const, + to: "/projects/ssh/$projectId/overview", params: { projectId } diff --git a/frontend/src/pages/ssh/SshCaByIDPage/route.tsx b/frontend/src/pages/ssh/SshCaByIDPage/route.tsx index e90f9736e..b9d97d8b9 100644 --- a/frontend/src/pages/ssh/SshCaByIDPage/route.tsx +++ b/frontend/src/pages/ssh/SshCaByIDPage/route.tsx @@ -3,7 +3,7 @@ import { createFileRoute, linkOptions } from "@tanstack/react-router"; import { SshCaByIDPage } from "./SshCaByIDPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/ca/$caId" + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/ca/$caId" )({ component: SshCaByIDPage, beforeLoad: ({ context, params }) => { @@ -13,7 +13,7 @@ export const Route = createFileRoute( { label: "Certificate Authorities", link: linkOptions({ - to: "/projects/$projectId/ssh/cas", + to: "/projects/ssh/$projectId/cas", params }) }, diff --git a/frontend/src/pages/ssh/SshCasPage/components/SshCaModal.tsx b/frontend/src/pages/ssh/SshCasPage/components/SshCaModal.tsx index 07bc964fb..758af52a9 100644 --- a/frontend/src/pages/ssh/SshCasPage/components/SshCaModal.tsx +++ b/frontend/src/pages/ssh/SshCasPage/components/SshCaModal.tsx @@ -22,7 +22,6 @@ import { SshCertKeyAlgorithm, sshCertKeyAlgorithms } from "@app/hooks/api/sshCa/constants"; -import { ProjectType } from "@app/hooks/api/workspace/types"; import { UsePopUpState } from "@app/hooks/usePopUp"; type Props = { @@ -126,7 +125,7 @@ export const SshCaModal = ({ popUp, handlePopUpToggle }: Props) => { }); navigate({ - to: `/projects/$projectId/${ProjectType.SSH}/ca/$caId` as const, + to: "/projects/ssh/$projectId/ca/$caId", params: { projectId, caId: newCaId diff --git a/frontend/src/pages/ssh/SshCasPage/components/SshCaTable.tsx b/frontend/src/pages/ssh/SshCasPage/components/SshCaTable.tsx index 6228c7130..37a086f37 100644 --- a/frontend/src/pages/ssh/SshCasPage/components/SshCaTable.tsx +++ b/frontend/src/pages/ssh/SshCasPage/components/SshCaTable.tsx @@ -24,7 +24,6 @@ import { import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context"; import { SshCaStatus, useListWorkspaceSshCas } from "@app/hooks/api"; import { caStatusToNameMap, getCaStatusBadgeVariant } from "@app/hooks/api/ca/constants"; -import { ProjectType } from "@app/hooks/api/workspace/types"; import { UsePopUpState } from "@app/hooks/usePopUp"; type Props = { @@ -62,7 +61,7 @@ export const SshCaTable = ({ handlePopUpOpen }: Props) => { key={`ca-${ca.id}`} onClick={() => navigate({ - to: `/projects/$projectId/${ProjectType.SSH}/ca/$caId` as const, + to: "/projects/ssh/$projectId/ca/$caId", params: { projectId: currentWorkspace.id, caId: ca.id diff --git a/frontend/src/pages/ssh/SshCasPage/route.tsx b/frontend/src/pages/ssh/SshCasPage/route.tsx index e2b9d2522..690e370a5 100644 --- a/frontend/src/pages/ssh/SshCasPage/route.tsx +++ b/frontend/src/pages/ssh/SshCasPage/route.tsx @@ -3,7 +3,7 @@ import { createFileRoute, linkOptions } from "@tanstack/react-router"; import { SshCasPage } from "./SshCasPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/cas" + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/cas" )({ component: SshCasPage, beforeLoad: ({ context, params }) => { @@ -13,7 +13,7 @@ export const Route = createFileRoute( { label: "Certificate Authorities", link: linkOptions({ - to: "/projects/$projectId/ssh/cas", + to: "/projects/ssh/$projectId/cas", params }) } diff --git a/frontend/src/pages/ssh/SshCertsPage/route.tsx b/frontend/src/pages/ssh/SshCertsPage/route.tsx index 0d31624c8..ebfecd77c 100644 --- a/frontend/src/pages/ssh/SshCertsPage/route.tsx +++ b/frontend/src/pages/ssh/SshCertsPage/route.tsx @@ -3,7 +3,7 @@ import { createFileRoute } from "@tanstack/react-router"; import { SshCertsPage } from "./SshCertsPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/certificates" + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/certificates" )({ component: SshCertsPage }); diff --git a/frontend/src/pages/ssh/SshHostGroupDetailsByIDPage/SshHostGroupDetailsByIDPage.tsx b/frontend/src/pages/ssh/SshHostGroupDetailsByIDPage/SshHostGroupDetailsByIDPage.tsx index 81b63c573..6b43e8324 100644 --- a/frontend/src/pages/ssh/SshHostGroupDetailsByIDPage/SshHostGroupDetailsByIDPage.tsx +++ b/frontend/src/pages/ssh/SshHostGroupDetailsByIDPage/SshHostGroupDetailsByIDPage.tsx @@ -18,7 +18,6 @@ import { import { ROUTE_PATHS } from "@app/const/routes"; import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context"; import { useDeleteSshHostGroup, useGetSshHostGroupById } from "@app/hooks/api"; -import { ProjectType } from "@app/hooks/api/workspace/types"; import { usePopUp } from "@app/hooks/usePopUp"; import { SshHostGroupModal } from "../SshHostsPage/components/SshHostGroupModal"; @@ -54,7 +53,7 @@ const Page = () => { handlePopUpClose("deleteSshHostGroup"); navigate({ - to: `/projects/$projectId/${ProjectType.SSH}/overview` as const, + to: "/projects/ssh/$projectId/overview", params: { projectId } diff --git a/frontend/src/pages/ssh/SshHostGroupDetailsByIDPage/route.tsx b/frontend/src/pages/ssh/SshHostGroupDetailsByIDPage/route.tsx index 45b536593..a9f7335a6 100644 --- a/frontend/src/pages/ssh/SshHostGroupDetailsByIDPage/route.tsx +++ b/frontend/src/pages/ssh/SshHostGroupDetailsByIDPage/route.tsx @@ -3,7 +3,7 @@ import { createFileRoute, linkOptions } from "@tanstack/react-router"; import { SshHostGroupDetailsByIDPage } from "./SshHostGroupDetailsByIDPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/ssh-host-groups/$sshHostGroupId" + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/ssh-host-groups/$sshHostGroupId" )({ component: SshHostGroupDetailsByIDPage, beforeLoad: ({ context, params }) => { @@ -13,7 +13,7 @@ export const Route = createFileRoute( { label: "Hosts", link: linkOptions({ - to: "/projects/$projectId/ssh/overview", + to: "/projects/ssh/$projectId/overview", params }) }, diff --git a/frontend/src/pages/ssh/SshHostsPage/components/SshHostGroupsTable.tsx b/frontend/src/pages/ssh/SshHostsPage/components/SshHostGroupsTable.tsx index 2d1e09393..daedabdc9 100644 --- a/frontend/src/pages/ssh/SshHostsPage/components/SshHostGroupsTable.tsx +++ b/frontend/src/pages/ssh/SshHostsPage/components/SshHostGroupsTable.tsx @@ -67,7 +67,7 @@ export const SshHostGroupsTable = ({ handlePopUpOpen }: Props) => { key={`ssh-host-group-${group.id}`} onClick={() => navigate({ - to: "/projects/$projectId/ssh/ssh-host-groups/$sshHostGroupId", + to: "/projects/ssh/$projectId/ssh-host-groups/$sshHostGroupId", params: { projectId: currentWorkspace.id, sshHostGroupId: group.id @@ -168,7 +168,7 @@ export const SshHostGroupsTable = ({ handlePopUpOpen }: Props) => { onClick={(e) => { e.stopPropagation(); navigate({ - to: "/projects/$projectId/ssh/ssh-host-groups/$sshHostGroupId", + to: "/projects/ssh/$projectId/ssh-host-groups/$sshHostGroupId", params: { projectId: currentWorkspace.id, sshHostGroupId: group.id diff --git a/frontend/src/pages/ssh/SshHostsPage/route.tsx b/frontend/src/pages/ssh/SshHostsPage/route.tsx index 2208a65cb..c9e9f8857 100644 --- a/frontend/src/pages/ssh/SshHostsPage/route.tsx +++ b/frontend/src/pages/ssh/SshHostsPage/route.tsx @@ -3,7 +3,7 @@ import { createFileRoute } from "@tanstack/react-router"; import { SshHostsPage } from "./SshHostsPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/overview" + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/overview" )({ component: SshHostsPage, beforeLoad: ({ context }) => { diff --git a/frontend/src/pages/ssh/layout.tsx b/frontend/src/pages/ssh/layout.tsx index 8354500b1..008aca393 100644 --- a/frontend/src/pages/ssh/layout.tsx +++ b/frontend/src/pages/ssh/layout.tsx @@ -1,9 +1,37 @@ import { createFileRoute } from "@tanstack/react-router"; +import { BreadcrumbTypes } from "@app/components/v2"; +import { workspaceKeys } from "@app/hooks/api"; +import { fetchUserProjectPermissions, roleQueryKeys } from "@app/hooks/api/roles/queries"; +import { fetchWorkspaceById } from "@app/hooks/api/workspace/queries"; +import { ProjectSelect } from "@app/layouts/ProjectLayout/components/ProjectSelect"; import { SshLayout } from "@app/layouts/SshLayout"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout" + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout" )({ - component: SshLayout + component: SshLayout, + beforeLoad: async ({ params, context }) => { + const project = await context.queryClient.ensureQueryData({ + queryKey: workspaceKeys.getWorkspaceById(params.projectId), + queryFn: () => fetchWorkspaceById(params.projectId) + }); + + await context.queryClient.ensureQueryData({ + queryKey: roleQueryKeys.getUserProjectPermissions({ + workspaceId: params.projectId + }), + queryFn: () => fetchUserProjectPermissions({ workspaceId: params.projectId }) + }); + + return { + project, + breadcrumbs: [ + { + type: BreadcrumbTypes.Component, + component: ProjectSelect + } + ] + }; + } }); diff --git a/frontend/src/routeTree.gen.ts b/frontend/src/routeTree.gen.ts index 40cad4a0e..c9c666a09 100644 --- a/frontend/src/routeTree.gen.ts +++ b/frontend/src/routeTree.gen.ts @@ -54,7 +54,6 @@ import { Route as organizationAdminPageRouteImport } from './pages/organization/ import { Route as organizationAccessManagementPageRouteImport } from './pages/organization/AccessManagementPage/route' import { Route as adminGeneralPageRouteImport } from './pages/admin/GeneralPage/route' import { Route as secretManagerRedirectsRedirectApprovalPageImport } from './pages/secret-manager/redirects/redirect-approval-page' -import { Route as projectLayoutImport } from './pages/project/layout' import { Route as adminUserIdentitiesResourcesPageRouteImport } from './pages/admin/UserIdentitiesResourcesPage/route' import { Route as adminOrganizationResourcesPageRouteImport } from './pages/admin/OrganizationResourcesPage/route' import { Route as adminMachineIdentitiesResourcesPageRouteImport } from './pages/admin/MachineIdentitiesResourcesPage/route' @@ -67,16 +66,26 @@ import { Route as organizationSettingsPageRouteImport } from './pages/organizati import { Route as organizationSecretSharingPageRouteImport } from './pages/organization/SecretSharingPage/route' import { Route as organizationGatewaysGatewayListPageRouteImport } from './pages/organization/Gateways/GatewayListPage/route' import { Route as organizationAppConnectionsAppConnectionsPageRouteImport } from './pages/organization/AppConnections/AppConnectionsPage/route' -import { Route as projectLayoutGeneralImport } from './pages/project/layout-general' -import { Route as organizationSettingsPageOauthCallbackPageRouteImport } from './pages/organization/SettingsPage/OauthCallbackPage/route' import { Route as sshLayoutImport } from './pages/ssh/layout' import { Route as secretScanningLayoutImport } from './pages/secret-scanning/layout' import { Route as secretManagerLayoutImport } from './pages/secret-manager/layout' import { Route as kmsLayoutImport } from './pages/kms/layout' import { Route as certManagerLayoutImport } from './pages/cert-manager/layout' -import { Route as projectSettingsPageRouteImport } from './pages/project/SettingsPage/route' -import { Route as projectAccessControlPageRouteImport } from './pages/project/AccessControlPage/route' -import { Route as organizationAppConnectionsOauthCallbackPageRouteImport } from './pages/organization/AppConnections/OauthCallbackPage/route' +import { Route as secretManagerIntegrationsRouteVercelOauthRedirectImport } from './pages/secret-manager/integrations/route-vercel-oauth-redirect' +import { Route as secretManagerIntegrationsRouteNetlifyOauthRedirectImport } from './pages/secret-manager/integrations/route-netlify-oauth-redirect' +import { Route as secretManagerIntegrationsRouteHerokuOauthRedirectImport } from './pages/secret-manager/integrations/route-heroku-oauth-redirect' +import { Route as secretManagerIntegrationsRouteGitlabOauthRedirectImport } from './pages/secret-manager/integrations/route-gitlab-oauth-redirect' +import { Route as secretManagerIntegrationsRouteGithubOauthRedirectImport } from './pages/secret-manager/integrations/route-github-oauth-redirect' +import { Route as secretManagerIntegrationsRouteGcpOauthRedirectImport } from './pages/secret-manager/integrations/route-gcp-oauth-redirect' +import { Route as secretManagerIntegrationsRouteBitbucketOauthRedirectImport } from './pages/secret-manager/integrations/route-bitbucket-oauth-redirect' +import { Route as secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectImport } from './pages/secret-manager/integrations/route-azure-key-vault-oauth-redirect' +import { Route as secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectImport } from './pages/secret-manager/integrations/route-azure-app-configurations-oauth-redirect' +import { Route as organizationSettingsPageOauthCallbackPageRouteImport } from './pages/organization/SettingsPage/OauthCallbackPage/route' +import { Route as projectAccessControlPageRouteSshImport } from './pages/project/AccessControlPage/route-ssh' +import { Route as projectAccessControlPageRouteSecretScanningImport } from './pages/project/AccessControlPage/route-secret-scanning' +import { Route as projectAccessControlPageRouteSecretManagerImport } from './pages/project/AccessControlPage/route-secret-manager' +import { Route as projectAccessControlPageRouteKmsImport } from './pages/project/AccessControlPage/route-kms' +import { Route as projectAccessControlPageRouteCertManagerImport } from './pages/project/AccessControlPage/route-cert-manager' import { Route as sshSettingsPageRouteImport } from './pages/ssh/SettingsPage/route' import { Route as sshSshHostsPageRouteImport } from './pages/ssh/SshHostsPage/route' import { Route as sshSshCertsPageRouteImport } from './pages/ssh/SshCertsPage/route' @@ -95,20 +104,28 @@ import { Route as certManagerSettingsPageRouteImport } from './pages/cert-manage import { Route as certManagerCertificatesPageRouteImport } from './pages/cert-manager/CertificatesPage/route' import { Route as certManagerCertificateAuthoritiesPageRouteImport } from './pages/cert-manager/CertificateAuthoritiesPage/route' import { Route as certManagerAlertingPageRouteImport } from './pages/cert-manager/AlertingPage/route' -import { Route as projectRoleDetailsBySlugPageRouteImport } from './pages/project/RoleDetailsBySlugPage/route' -import { Route as projectMemberDetailsByIDPageRouteImport } from './pages/project/MemberDetailsByIDPage/route' -import { Route as projectIdentityDetailsByIDPageRouteImport } from './pages/project/IdentityDetailsByIDPage/route' -import { Route as projectGroupDetailsByIDPageRouteImport } from './pages/project/GroupDetailsByIDPage/route' -import { Route as secretManagerIntegrationsRouteVercelOauthRedirectImport } from './pages/secret-manager/integrations/route-vercel-oauth-redirect' -import { Route as secretManagerIntegrationsRouteNetlifyOauthRedirectImport } from './pages/secret-manager/integrations/route-netlify-oauth-redirect' -import { Route as secretManagerIntegrationsRouteHerokuOauthRedirectImport } from './pages/secret-manager/integrations/route-heroku-oauth-redirect' -import { Route as secretManagerIntegrationsRouteGitlabOauthRedirectImport } from './pages/secret-manager/integrations/route-gitlab-oauth-redirect' -import { Route as secretManagerIntegrationsRouteGithubOauthRedirectImport } from './pages/secret-manager/integrations/route-github-oauth-redirect' -import { Route as secretManagerIntegrationsRouteGcpOauthRedirectImport } from './pages/secret-manager/integrations/route-gcp-oauth-redirect' -import { Route as secretManagerIntegrationsRouteBitbucketOauthRedirectImport } from './pages/secret-manager/integrations/route-bitbucket-oauth-redirect' -import { Route as secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectImport } from './pages/secret-manager/integrations/route-azure-key-vault-oauth-redirect' -import { Route as secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectImport } from './pages/secret-manager/integrations/route-azure-app-configurations-oauth-redirect' +import { Route as organizationAppConnectionsOauthCallbackPageRouteImport } from './pages/organization/AppConnections/OauthCallbackPage/route' +import { Route as projectRoleDetailsBySlugPageRouteSshImport } from './pages/project/RoleDetailsBySlugPage/route-ssh' +import { Route as projectMemberDetailsByIDPageRouteSshImport } from './pages/project/MemberDetailsByIDPage/route-ssh' +import { Route as projectIdentityDetailsByIDPageRouteSshImport } from './pages/project/IdentityDetailsByIDPage/route-ssh' +import { Route as projectGroupDetailsByIDPageRouteSshImport } from './pages/project/GroupDetailsByIDPage/route-ssh' +import { Route as projectRoleDetailsBySlugPageRouteSecretScanningImport } from './pages/project/RoleDetailsBySlugPage/route-secret-scanning' +import { Route as projectMemberDetailsByIDPageRouteSecretScanningImport } from './pages/project/MemberDetailsByIDPage/route-secret-scanning' +import { Route as projectIdentityDetailsByIDPageRouteSecretScanningImport } from './pages/project/IdentityDetailsByIDPage/route-secret-scanning' +import { Route as projectGroupDetailsByIDPageRouteSecretScanningImport } from './pages/project/GroupDetailsByIDPage/route-secret-scanning' +import { Route as projectRoleDetailsBySlugPageRouteSecretManagerImport } from './pages/project/RoleDetailsBySlugPage/route-secret-manager' +import { Route as projectMemberDetailsByIDPageRouteSecretManagerImport } from './pages/project/MemberDetailsByIDPage/route-secret-manager' +import { Route as projectIdentityDetailsByIDPageRouteSecretManagerImport } from './pages/project/IdentityDetailsByIDPage/route-secret-manager' +import { Route as projectGroupDetailsByIDPageRouteSecretManagerImport } from './pages/project/GroupDetailsByIDPage/route-secret-manager' +import { Route as projectRoleDetailsBySlugPageRouteKmsImport } from './pages/project/RoleDetailsBySlugPage/route-kms' +import { Route as projectMemberDetailsByIDPageRouteKmsImport } from './pages/project/MemberDetailsByIDPage/route-kms' +import { Route as projectIdentityDetailsByIDPageRouteKmsImport } from './pages/project/IdentityDetailsByIDPage/route-kms' +import { Route as projectGroupDetailsByIDPageRouteKmsImport } from './pages/project/GroupDetailsByIDPage/route-kms' +import { Route as projectRoleDetailsBySlugPageRouteCertManagerImport } from './pages/project/RoleDetailsBySlugPage/route-cert-manager' import { Route as certManagerPkiCollectionDetailsByIDPageRoutesImport } from './pages/cert-manager/PkiCollectionDetailsByIDPage/routes' +import { Route as projectMemberDetailsByIDPageRouteCertManagerImport } from './pages/project/MemberDetailsByIDPage/route-cert-manager' +import { Route as projectIdentityDetailsByIDPageRouteCertManagerImport } from './pages/project/IdentityDetailsByIDPage/route-cert-manager' +import { Route as projectGroupDetailsByIDPageRouteCertManagerImport } from './pages/project/GroupDetailsByIDPage/route-cert-manager' import { Route as sshSshHostGroupDetailsByIDPageRouteImport } from './pages/ssh/SshHostGroupDetailsByIDPage/route' import { Route as sshSshCaByIDPageRouteImport } from './pages/ssh/SshCaByIDPage/route' import { Route as secretManagerSecretDashboardPageRouteImport } from './pages/secret-manager/SecretDashboardPage/route' @@ -217,14 +234,13 @@ const AuthenticateInjectOrgDetailsAdminImport = createFileRoute( const AuthenticateInjectOrgDetailsOrgLayoutOrganizationImport = createFileRoute( '/_authenticate/_inject-org-details/_org-layout/organization', )() +const AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport = createFileRoute( + '/_authenticate/_inject-org-details/_org-layout/integrations', +)() const AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdImport = createFileRoute( '/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId', )() -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdImport = - createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId', - )() const AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsImport = createFileRoute( '/_authenticate/_inject-org-details/_org-layout/organization/settings', @@ -241,53 +257,49 @@ const AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsImport = createFileRoute( '/_authenticate/_inject-org-details/_org-layout/organization/app-connections', )() -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSshImport = +const AuthenticateInjectOrgDetailsOrgLayoutProjectsSshProjectIdImport = createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh', + '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId', )() -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningImport = +const AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdImport = createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning', + '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId', )() -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerImport = +const AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdImport = createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager', + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId', )() -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutKmsImport = +const AuthenticateInjectOrgDetailsOrgLayoutProjectsKmsProjectIdImport = createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms', + '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId', )() -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsImport = +const AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdImport = createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations', + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId', )() -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerImport = +const AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesImport = createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager', + '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources', )() -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningSecretScanningLayoutDataSourcesImport = +const AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport = createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/data-sources', + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations', )() -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport = +const AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutSubscribersImport = createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations', + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/subscribers', )() -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutSubscribersImport = +const AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesImport = createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/subscribers', + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates', )() -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutCertificateTemplatesImport = +const AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdImport = createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificate-templates', + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId', )() -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdImport = +const AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdImport = createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId', - )() -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdImport = - createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/$commitId', + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId', )() // Create/Update Routes @@ -489,6 +501,13 @@ const AuthenticateInjectOrgDetailsOrgLayoutOrganizationRoute = getParentRoute: () => organizationLayoutRoute, } as any) +const AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute = + AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport.update({ + id: '/integrations', + path: '/integrations', + getParentRoute: () => organizationLayoutRoute, + } as any) + const authProviderSuccessPageRouteRoute = authProviderSuccessPageRouteImport.update({ id: '/provider/success', @@ -518,13 +537,6 @@ const AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRoute = getParentRoute: () => organizationLayoutRoute, } as any) -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdRoute = - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdImport.update({ - id: '/projects/$projectId', - path: '/projects/$projectId', - getParentRoute: () => organizationLayoutRoute, - } as any) - const AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRoute = AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsImport.update({ id: '/settings', @@ -645,11 +657,46 @@ const secretManagerRedirectsRedirectApprovalPageRoute = AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRoute, } as any) -const projectLayoutRoute = projectLayoutImport.update({ - id: '/_project-layout', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdRoute, -} as any) +const AuthenticateInjectOrgDetailsOrgLayoutProjectsSshProjectIdRoute = + AuthenticateInjectOrgDetailsOrgLayoutProjectsSshProjectIdImport.update({ + id: '/projects/ssh/$projectId', + path: '/projects/ssh/$projectId', + getParentRoute: () => organizationLayoutRoute, + } as any) + +const AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdRoute = + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdImport.update( + { + id: '/projects/secret-scanning/$projectId', + path: '/projects/secret-scanning/$projectId', + getParentRoute: () => organizationLayoutRoute, + } as any, + ) + +const AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdRoute = + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdImport.update( + { + id: '/projects/secret-management/$projectId', + path: '/projects/secret-management/$projectId', + getParentRoute: () => organizationLayoutRoute, + } as any, + ) + +const AuthenticateInjectOrgDetailsOrgLayoutProjectsKmsProjectIdRoute = + AuthenticateInjectOrgDetailsOrgLayoutProjectsKmsProjectIdImport.update({ + id: '/projects/kms/$projectId', + path: '/projects/kms/$projectId', + getParentRoute: () => organizationLayoutRoute, + } as any) + +const AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdRoute = + AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdImport.update( + { + id: '/projects/cert-management/$projectId', + path: '/projects/cert-management/$projectId', + getParentRoute: () => organizationLayoutRoute, + } as any, + ) const adminUserIdentitiesResourcesPageRouteRoute = adminUserIdentitiesResourcesPageRouteImport.update({ @@ -744,65 +791,110 @@ const organizationAppConnectionsAppConnectionsPageRouteRoute = AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRoute, } as any) -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSshRoute = - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSshImport.update( - { - id: '/ssh', - path: '/ssh', - getParentRoute: () => projectLayoutRoute, - } as any, - ) - -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningRoute = - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningImport.update( - { - id: '/secret-scanning', - path: '/secret-scanning', - getParentRoute: () => projectLayoutRoute, - } as any, - ) - -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerRoute = - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerImport.update( - { - id: '/secret-manager', - path: '/secret-manager', - getParentRoute: () => projectLayoutRoute, - } as any, - ) - -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutKmsRoute = - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutKmsImport.update( - { - id: '/kms', - path: '/kms', - getParentRoute: () => projectLayoutRoute, - } as any, - ) - -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsRoute = - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsImport.update( - { - id: '/integrations', - path: '/integrations', - getParentRoute: () => projectLayoutRoute, - } as any, - ) - -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerRoute = - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerImport.update( - { - id: '/cert-manager', - path: '/cert-manager', - getParentRoute: () => projectLayoutRoute, - } as any, - ) - -const projectLayoutGeneralRoute = projectLayoutGeneralImport.update({ - id: '/_project-general-layout', - getParentRoute: () => projectLayoutRoute, +const sshLayoutRoute = sshLayoutImport.update({ + id: '/_ssh-layout', + getParentRoute: () => + AuthenticateInjectOrgDetailsOrgLayoutProjectsSshProjectIdRoute, } as any) +const secretScanningLayoutRoute = secretScanningLayoutImport.update({ + id: '/_secret-scanning-layout', + getParentRoute: () => + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdRoute, +} as any) + +const secretManagerLayoutRoute = secretManagerLayoutImport.update({ + id: '/_secret-manager-layout', + getParentRoute: () => + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdRoute, +} as any) + +const kmsLayoutRoute = kmsLayoutImport.update({ + id: '/_kms-layout', + getParentRoute: () => + AuthenticateInjectOrgDetailsOrgLayoutProjectsKmsProjectIdRoute, +} as any) + +const certManagerLayoutRoute = certManagerLayoutImport.update({ + id: '/_cert-manager-layout', + getParentRoute: () => + AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdRoute, +} as any) + +const secretManagerIntegrationsRouteVercelOauthRedirectRoute = + secretManagerIntegrationsRouteVercelOauthRedirectImport.update({ + id: '/vercel/oauth2/callback', + path: '/vercel/oauth2/callback', + getParentRoute: () => + AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute, + } as any) + +const secretManagerIntegrationsRouteNetlifyOauthRedirectRoute = + secretManagerIntegrationsRouteNetlifyOauthRedirectImport.update({ + id: '/netlify/oauth2/callback', + path: '/netlify/oauth2/callback', + getParentRoute: () => + AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute, + } as any) + +const secretManagerIntegrationsRouteHerokuOauthRedirectRoute = + secretManagerIntegrationsRouteHerokuOauthRedirectImport.update({ + id: '/heroku/oauth2/callback', + path: '/heroku/oauth2/callback', + getParentRoute: () => + AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute, + } as any) + +const secretManagerIntegrationsRouteGitlabOauthRedirectRoute = + secretManagerIntegrationsRouteGitlabOauthRedirectImport.update({ + id: '/gitlab/oauth2/callback', + path: '/gitlab/oauth2/callback', + getParentRoute: () => + AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute, + } as any) + +const secretManagerIntegrationsRouteGithubOauthRedirectRoute = + secretManagerIntegrationsRouteGithubOauthRedirectImport.update({ + id: '/github/oauth2/callback', + path: '/github/oauth2/callback', + getParentRoute: () => + AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute, + } as any) + +const secretManagerIntegrationsRouteGcpOauthRedirectRoute = + secretManagerIntegrationsRouteGcpOauthRedirectImport.update({ + id: '/gcp-secret-manager/oauth2/callback', + path: '/gcp-secret-manager/oauth2/callback', + getParentRoute: () => + AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute, + } as any) + +const secretManagerIntegrationsRouteBitbucketOauthRedirectRoute = + secretManagerIntegrationsRouteBitbucketOauthRedirectImport.update({ + id: '/bitbucket/oauth2/callback', + path: '/bitbucket/oauth2/callback', + getParentRoute: () => + AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute, + } as any) + +const secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectRoute = + secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectImport.update({ + id: '/azure-key-vault/oauth2/callback', + path: '/azure-key-vault/oauth2/callback', + getParentRoute: () => + AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute, + } as any) + +const secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectRoute = + secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectImport.update( + { + id: '/azure-app-configuration/oauth2/callback', + path: '/azure-app-configuration/oauth2/callback', + getParentRoute: () => + AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute, + } as any, + ) + const organizationSettingsPageOauthCallbackPageRouteRoute = organizationSettingsPageOauthCallbackPageRouteImport.update({ id: '/oauth/callback', @@ -811,59 +903,15 @@ const organizationSettingsPageOauthCallbackPageRouteRoute = AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRoute, } as any) -const sshLayoutRoute = sshLayoutImport.update({ - id: '/_ssh-layout', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSshRoute, -} as any) - -const secretScanningLayoutRoute = secretScanningLayoutImport.update({ - id: '/_secret-scanning-layout', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningRoute, -} as any) - -const secretManagerLayoutRoute = secretManagerLayoutImport.update({ - id: '/_secret-manager-layout', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerRoute, -} as any) - -const kmsLayoutRoute = kmsLayoutImport.update({ - id: '/_kms-layout', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutKmsRoute, -} as any) - -const certManagerLayoutRoute = certManagerLayoutImport.update({ - id: '/_cert-manager-layout', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerRoute, -} as any) - -const projectSettingsPageRouteRoute = projectSettingsPageRouteImport.update({ - id: '/settings', - path: '/settings', - getParentRoute: () => projectLayoutGeneralRoute, -} as any) - -const projectAccessControlPageRouteRoute = - projectAccessControlPageRouteImport.update({ +const projectAccessControlPageRouteSshRoute = + projectAccessControlPageRouteSshImport.update({ id: '/access-management', path: '/access-management', - getParentRoute: () => projectLayoutGeneralRoute, + getParentRoute: () => sshLayoutRoute, } as any) -const organizationAppConnectionsOauthCallbackPageRouteRoute = - organizationAppConnectionsOauthCallbackPageRouteImport.update({ - id: '/$appConnection/oauth/callback', - path: '/$appConnection/oauth/callback', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRoute, - } as any) - -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningSecretScanningLayoutDataSourcesRoute = - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningSecretScanningLayoutDataSourcesImport.update( +const AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRoute = + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesImport.update( { id: '/data-sources', path: '/data-sources', @@ -871,8 +919,15 @@ const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretS } as any, ) -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute = - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport.update( +const projectAccessControlPageRouteSecretScanningRoute = + projectAccessControlPageRouteSecretScanningImport.update({ + id: '/access-management', + path: '/access-management', + getParentRoute: () => secretScanningLayoutRoute, + } as any) + +const AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute = + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport.update( { id: '/integrations', path: '/integrations', @@ -880,8 +935,22 @@ const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretM } as any, ) -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutSubscribersRoute = - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutSubscribersImport.update( +const projectAccessControlPageRouteSecretManagerRoute = + projectAccessControlPageRouteSecretManagerImport.update({ + id: '/access-management', + path: '/access-management', + getParentRoute: () => secretManagerLayoutRoute, + } as any) + +const projectAccessControlPageRouteKmsRoute = + projectAccessControlPageRouteKmsImport.update({ + id: '/access-management', + path: '/access-management', + getParentRoute: () => kmsLayoutRoute, + } as any) + +const AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutSubscribersRoute = + AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutSubscribersImport.update( { id: '/subscribers', path: '/subscribers', @@ -889,8 +958,8 @@ const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertMan } as any, ) -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutCertificateTemplatesRoute = - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutCertificateTemplatesImport.update( +const AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesRoute = + AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesImport.update( { id: '/certificate-templates', path: '/certificate-templates', @@ -898,6 +967,13 @@ const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertMan } as any, ) +const projectAccessControlPageRouteCertManagerRoute = + projectAccessControlPageRouteCertManagerImport.update({ + id: '/access-management', + path: '/access-management', + getParentRoute: () => certManagerLayoutRoute, + } as any) + const sshSettingsPageRouteRoute = sshSettingsPageRouteImport.update({ id: '/settings', path: '/settings', @@ -1017,107 +1093,132 @@ const certManagerAlertingPageRouteRoute = getParentRoute: () => certManagerLayoutRoute, } as any) -const projectRoleDetailsBySlugPageRouteRoute = - projectRoleDetailsBySlugPageRouteImport.update({ +const organizationAppConnectionsOauthCallbackPageRouteRoute = + organizationAppConnectionsOauthCallbackPageRouteImport.update({ + id: '/$appConnection/oauth/callback', + path: '/$appConnection/oauth/callback', + getParentRoute: () => + AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRoute, + } as any) + +const projectRoleDetailsBySlugPageRouteSshRoute = + projectRoleDetailsBySlugPageRouteSshImport.update({ id: '/roles/$roleSlug', path: '/roles/$roleSlug', - getParentRoute: () => projectLayoutGeneralRoute, + getParentRoute: () => sshLayoutRoute, } as any) -const projectMemberDetailsByIDPageRouteRoute = - projectMemberDetailsByIDPageRouteImport.update({ +const projectMemberDetailsByIDPageRouteSshRoute = + projectMemberDetailsByIDPageRouteSshImport.update({ id: '/members/$membershipId', path: '/members/$membershipId', - getParentRoute: () => projectLayoutGeneralRoute, + getParentRoute: () => sshLayoutRoute, } as any) -const projectIdentityDetailsByIDPageRouteRoute = - projectIdentityDetailsByIDPageRouteImport.update({ +const projectIdentityDetailsByIDPageRouteSshRoute = + projectIdentityDetailsByIDPageRouteSshImport.update({ id: '/identities/$identityId', path: '/identities/$identityId', - getParentRoute: () => projectLayoutGeneralRoute, + getParentRoute: () => sshLayoutRoute, } as any) -const projectGroupDetailsByIDPageRouteRoute = - projectGroupDetailsByIDPageRouteImport.update({ +const projectGroupDetailsByIDPageRouteSshRoute = + projectGroupDetailsByIDPageRouteSshImport.update({ id: '/groups/$groupId', path: '/groups/$groupId', - getParentRoute: () => projectLayoutGeneralRoute, + getParentRoute: () => sshLayoutRoute, } as any) -const secretManagerIntegrationsRouteVercelOauthRedirectRoute = - secretManagerIntegrationsRouteVercelOauthRedirectImport.update({ - id: '/vercel/oauth2/callback', - path: '/vercel/oauth2/callback', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsRoute, +const projectRoleDetailsBySlugPageRouteSecretScanningRoute = + projectRoleDetailsBySlugPageRouteSecretScanningImport.update({ + id: '/roles/$roleSlug', + path: '/roles/$roleSlug', + getParentRoute: () => secretScanningLayoutRoute, } as any) -const secretManagerIntegrationsRouteNetlifyOauthRedirectRoute = - secretManagerIntegrationsRouteNetlifyOauthRedirectImport.update({ - id: '/netlify/oauth2/callback', - path: '/netlify/oauth2/callback', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsRoute, +const projectMemberDetailsByIDPageRouteSecretScanningRoute = + projectMemberDetailsByIDPageRouteSecretScanningImport.update({ + id: '/members/$membershipId', + path: '/members/$membershipId', + getParentRoute: () => secretScanningLayoutRoute, } as any) -const secretManagerIntegrationsRouteHerokuOauthRedirectRoute = - secretManagerIntegrationsRouteHerokuOauthRedirectImport.update({ - id: '/heroku/oauth2/callback', - path: '/heroku/oauth2/callback', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsRoute, +const projectIdentityDetailsByIDPageRouteSecretScanningRoute = + projectIdentityDetailsByIDPageRouteSecretScanningImport.update({ + id: '/identities/$identityId', + path: '/identities/$identityId', + getParentRoute: () => secretScanningLayoutRoute, } as any) -const secretManagerIntegrationsRouteGitlabOauthRedirectRoute = - secretManagerIntegrationsRouteGitlabOauthRedirectImport.update({ - id: '/gitlab/oauth2/callback', - path: '/gitlab/oauth2/callback', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsRoute, +const projectGroupDetailsByIDPageRouteSecretScanningRoute = + projectGroupDetailsByIDPageRouteSecretScanningImport.update({ + id: '/groups/$groupId', + path: '/groups/$groupId', + getParentRoute: () => secretScanningLayoutRoute, } as any) -const secretManagerIntegrationsRouteGithubOauthRedirectRoute = - secretManagerIntegrationsRouteGithubOauthRedirectImport.update({ - id: '/github/oauth2/callback', - path: '/github/oauth2/callback', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsRoute, +const projectRoleDetailsBySlugPageRouteSecretManagerRoute = + projectRoleDetailsBySlugPageRouteSecretManagerImport.update({ + id: '/roles/$roleSlug', + path: '/roles/$roleSlug', + getParentRoute: () => secretManagerLayoutRoute, } as any) -const secretManagerIntegrationsRouteGcpOauthRedirectRoute = - secretManagerIntegrationsRouteGcpOauthRedirectImport.update({ - id: '/gcp-secret-manager/oauth2/callback', - path: '/gcp-secret-manager/oauth2/callback', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsRoute, +const projectMemberDetailsByIDPageRouteSecretManagerRoute = + projectMemberDetailsByIDPageRouteSecretManagerImport.update({ + id: '/members/$membershipId', + path: '/members/$membershipId', + getParentRoute: () => secretManagerLayoutRoute, } as any) -const secretManagerIntegrationsRouteBitbucketOauthRedirectRoute = - secretManagerIntegrationsRouteBitbucketOauthRedirectImport.update({ - id: '/bitbucket/oauth2/callback', - path: '/bitbucket/oauth2/callback', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsRoute, +const projectIdentityDetailsByIDPageRouteSecretManagerRoute = + projectIdentityDetailsByIDPageRouteSecretManagerImport.update({ + id: '/identities/$identityId', + path: '/identities/$identityId', + getParentRoute: () => secretManagerLayoutRoute, } as any) -const secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectRoute = - secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectImport.update({ - id: '/azure-key-vault/oauth2/callback', - path: '/azure-key-vault/oauth2/callback', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsRoute, +const projectGroupDetailsByIDPageRouteSecretManagerRoute = + projectGroupDetailsByIDPageRouteSecretManagerImport.update({ + id: '/groups/$groupId', + path: '/groups/$groupId', + getParentRoute: () => secretManagerLayoutRoute, } as any) -const secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectRoute = - secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectImport.update( - { - id: '/azure-app-configuration/oauth2/callback', - path: '/azure-app-configuration/oauth2/callback', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsRoute, - } as any, - ) +const projectRoleDetailsBySlugPageRouteKmsRoute = + projectRoleDetailsBySlugPageRouteKmsImport.update({ + id: '/roles/$roleSlug', + path: '/roles/$roleSlug', + getParentRoute: () => kmsLayoutRoute, + } as any) + +const projectMemberDetailsByIDPageRouteKmsRoute = + projectMemberDetailsByIDPageRouteKmsImport.update({ + id: '/members/$membershipId', + path: '/members/$membershipId', + getParentRoute: () => kmsLayoutRoute, + } as any) + +const projectIdentityDetailsByIDPageRouteKmsRoute = + projectIdentityDetailsByIDPageRouteKmsImport.update({ + id: '/identities/$identityId', + path: '/identities/$identityId', + getParentRoute: () => kmsLayoutRoute, + } as any) + +const projectGroupDetailsByIDPageRouteKmsRoute = + projectGroupDetailsByIDPageRouteKmsImport.update({ + id: '/groups/$groupId', + path: '/groups/$groupId', + getParentRoute: () => kmsLayoutRoute, + } as any) + +const projectRoleDetailsBySlugPageRouteCertManagerRoute = + projectRoleDetailsBySlugPageRouteCertManagerImport.update({ + id: '/roles/$roleSlug', + path: '/roles/$roleSlug', + getParentRoute: () => certManagerLayoutRoute, + } as any) const certManagerPkiCollectionDetailsByIDPageRoutesRoute = certManagerPkiCollectionDetailsByIDPageRoutesImport.update({ @@ -1126,6 +1227,27 @@ const certManagerPkiCollectionDetailsByIDPageRoutesRoute = getParentRoute: () => certManagerLayoutRoute, } as any) +const projectMemberDetailsByIDPageRouteCertManagerRoute = + projectMemberDetailsByIDPageRouteCertManagerImport.update({ + id: '/members/$membershipId', + path: '/members/$membershipId', + getParentRoute: () => certManagerLayoutRoute, + } as any) + +const projectIdentityDetailsByIDPageRouteCertManagerRoute = + projectIdentityDetailsByIDPageRouteCertManagerImport.update({ + id: '/identities/$identityId', + path: '/identities/$identityId', + getParentRoute: () => certManagerLayoutRoute, + } as any) + +const projectGroupDetailsByIDPageRouteCertManagerRoute = + projectGroupDetailsByIDPageRouteCertManagerImport.update({ + id: '/groups/$groupId', + path: '/groups/$groupId', + getParentRoute: () => certManagerLayoutRoute, + } as any) + const sshSshHostGroupDetailsByIDPageRouteRoute = sshSshHostGroupDetailsByIDPageRouteImport.update({ id: '/ssh-host-groups/$sshHostGroupId', @@ -1151,7 +1273,7 @@ const secretManagerIntegrationsSelectIntegrationAuthPageRouteRoute = id: '/select-integration-auth', path: '/select-integration-auth', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsDetailsByIDPageRouteRoute = @@ -1159,7 +1281,7 @@ const secretManagerIntegrationsDetailsByIDPageRouteRoute = id: '/$integrationId', path: '/$integrationId', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const certManagerPkiSubscriberDetailsByIDPageRouteRoute = @@ -1167,7 +1289,7 @@ const certManagerPkiSubscriberDetailsByIDPageRouteRoute = id: '/$subscriberName', path: '/$subscriberName', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutSubscribersRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutSubscribersRoute, } as any) const certManagerCertAuthDetailsByIDPageRouteRoute = @@ -1182,7 +1304,7 @@ const secretScanningSecretScanningDataSourcesPageRouteRoute = id: '/', path: '/', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningSecretScanningLayoutDataSourcesRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRoute, } as any) const secretManagerIntegrationsListPageRouteRoute = @@ -1190,7 +1312,7 @@ const secretManagerIntegrationsListPageRouteRoute = id: '/', path: '/', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const certManagerPkiSubscribersPageRouteRoute = @@ -1198,7 +1320,7 @@ const certManagerPkiSubscribersPageRouteRoute = id: '/', path: '/', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutSubscribersRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutSubscribersRoute, } as any) const certManagerPkiTemplateListPageRouteRoute = @@ -1206,11 +1328,11 @@ const certManagerPkiTemplateListPageRouteRoute = id: '/', path: '/', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutCertificateTemplatesRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesRoute, } as any) -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdRoute = - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdImport.update( +const AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRoute = + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdImport.update( { id: '/commits/$environment/$folderId', path: '/commits/$environment/$folderId', @@ -1223,7 +1345,7 @@ const secretScanningSecretScanningDataSourceByIdPageRouteRoute = id: '/$type/$dataSourceId', path: '/$type/$dataSourceId', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningSecretScanningLayoutDataSourcesRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRoute, } as any) const secretManagerIntegrationsWindmillConfigurePageRouteRoute = @@ -1231,7 +1353,7 @@ const secretManagerIntegrationsWindmillConfigurePageRouteRoute = id: '/windmill/create', path: '/windmill/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsWindmillAuthorizePageRouteRoute = @@ -1239,7 +1361,7 @@ const secretManagerIntegrationsWindmillAuthorizePageRouteRoute = id: '/windmill/authorize', path: '/windmill/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsVercelConfigurePageRouteRoute = @@ -1247,7 +1369,7 @@ const secretManagerIntegrationsVercelConfigurePageRouteRoute = id: '/vercel/create', path: '/vercel/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsTravisCIConfigurePageRouteRoute = @@ -1255,7 +1377,7 @@ const secretManagerIntegrationsTravisCIConfigurePageRouteRoute = id: '/travisci/create', path: '/travisci/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsTravisCIAuthorizePageRouteRoute = @@ -1263,7 +1385,7 @@ const secretManagerIntegrationsTravisCIAuthorizePageRouteRoute = id: '/travisci/authorize', path: '/travisci/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsTerraformCloudConfigurePageRouteRoute = @@ -1271,7 +1393,7 @@ const secretManagerIntegrationsTerraformCloudConfigurePageRouteRoute = id: '/terraform-cloud/create', path: '/terraform-cloud/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsTerraformCloudAuthorizePageRouteRoute = @@ -1279,7 +1401,7 @@ const secretManagerIntegrationsTerraformCloudAuthorizePageRouteRoute = id: '/terraform-cloud/authorize', path: '/terraform-cloud/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsTeamcityConfigurePageRouteRoute = @@ -1287,7 +1409,7 @@ const secretManagerIntegrationsTeamcityConfigurePageRouteRoute = id: '/teamcity/create', path: '/teamcity/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsTeamcityAuthorizePageRouteRoute = @@ -1295,7 +1417,7 @@ const secretManagerIntegrationsTeamcityAuthorizePageRouteRoute = id: '/teamcity/authorize', path: '/teamcity/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsSupabaseConfigurePageRouteRoute = @@ -1303,7 +1425,7 @@ const secretManagerIntegrationsSupabaseConfigurePageRouteRoute = id: '/supabase/create', path: '/supabase/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsSupabaseAuthorizePageRouteRoute = @@ -1311,7 +1433,7 @@ const secretManagerIntegrationsSupabaseAuthorizePageRouteRoute = id: '/supabase/authorize', path: '/supabase/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsRundeckConfigurePageRouteRoute = @@ -1319,7 +1441,7 @@ const secretManagerIntegrationsRundeckConfigurePageRouteRoute = id: '/rundeck/create', path: '/rundeck/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsRundeckAuthorizePageRouteRoute = @@ -1327,7 +1449,7 @@ const secretManagerIntegrationsRundeckAuthorizePageRouteRoute = id: '/rundeck/authorize', path: '/rundeck/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsRenderConfigurePageRouteRoute = @@ -1335,7 +1457,7 @@ const secretManagerIntegrationsRenderConfigurePageRouteRoute = id: '/render/create', path: '/render/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsRenderAuthorizePageRouteRoute = @@ -1343,7 +1465,7 @@ const secretManagerIntegrationsRenderAuthorizePageRouteRoute = id: '/render/authorize', path: '/render/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsRailwayConfigurePageRouteRoute = @@ -1351,7 +1473,7 @@ const secretManagerIntegrationsRailwayConfigurePageRouteRoute = id: '/railway/create', path: '/railway/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsRailwayAuthorizePageRouteRoute = @@ -1359,7 +1481,7 @@ const secretManagerIntegrationsRailwayAuthorizePageRouteRoute = id: '/railway/authorize', path: '/railway/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsQoveryConfigurePageRouteRoute = @@ -1367,7 +1489,7 @@ const secretManagerIntegrationsQoveryConfigurePageRouteRoute = id: '/qovery/create', path: '/qovery/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsQoveryAuthorizePageRouteRoute = @@ -1375,7 +1497,7 @@ const secretManagerIntegrationsQoveryAuthorizePageRouteRoute = id: '/qovery/authorize', path: '/qovery/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsOctopusDeployConfigurePageRouteRoute = @@ -1383,7 +1505,7 @@ const secretManagerIntegrationsOctopusDeployConfigurePageRouteRoute = id: '/octopus-deploy/create', path: '/octopus-deploy/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsOctopusDeployAuthorizePageRouteRoute = @@ -1391,7 +1513,7 @@ const secretManagerIntegrationsOctopusDeployAuthorizePageRouteRoute = id: '/octopus-deploy/authorize', path: '/octopus-deploy/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsNorthflankConfigurePageRouteRoute = @@ -1399,7 +1521,7 @@ const secretManagerIntegrationsNorthflankConfigurePageRouteRoute = id: '/northflank/create', path: '/northflank/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsNorthflankAuthorizePageRouteRoute = @@ -1407,7 +1529,7 @@ const secretManagerIntegrationsNorthflankAuthorizePageRouteRoute = id: '/northflank/authorize', path: '/northflank/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsNetlifyConfigurePageRouteRoute = @@ -1415,7 +1537,7 @@ const secretManagerIntegrationsNetlifyConfigurePageRouteRoute = id: '/netlify/create', path: '/netlify/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsLaravelForgeConfigurePageRouteRoute = @@ -1423,7 +1545,7 @@ const secretManagerIntegrationsLaravelForgeConfigurePageRouteRoute = id: '/laravel-forge/create', path: '/laravel-forge/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsLaravelForgeAuthorizePageRouteRoute = @@ -1431,7 +1553,7 @@ const secretManagerIntegrationsLaravelForgeAuthorizePageRouteRoute = id: '/laravel-forge/authorize', path: '/laravel-forge/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsHerokuConfigurePageRouteRoute = @@ -1439,7 +1561,7 @@ const secretManagerIntegrationsHerokuConfigurePageRouteRoute = id: '/heroku/create', path: '/heroku/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsHasuraCloudConfigurePageRouteRoute = @@ -1447,7 +1569,7 @@ const secretManagerIntegrationsHasuraCloudConfigurePageRouteRoute = id: '/hasura-cloud/create', path: '/hasura-cloud/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsHasuraCloudAuthorizePageRouteRoute = @@ -1455,7 +1577,7 @@ const secretManagerIntegrationsHasuraCloudAuthorizePageRouteRoute = id: '/hasura-cloud/authorize', path: '/hasura-cloud/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsHashicorpVaultConfigurePageRouteRoute = @@ -1463,7 +1585,7 @@ const secretManagerIntegrationsHashicorpVaultConfigurePageRouteRoute = id: '/hashicorp-vault/create', path: '/hashicorp-vault/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsHashicorpVaultAuthorizePageRouteRoute = @@ -1471,7 +1593,7 @@ const secretManagerIntegrationsHashicorpVaultAuthorizePageRouteRoute = id: '/hashicorp-vault/authorize', path: '/hashicorp-vault/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsGitlabConfigurePageRouteRoute = @@ -1479,7 +1601,7 @@ const secretManagerIntegrationsGitlabConfigurePageRouteRoute = id: '/gitlab/create', path: '/gitlab/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsGitlabAuthorizePageRouteRoute = @@ -1487,7 +1609,7 @@ const secretManagerIntegrationsGitlabAuthorizePageRouteRoute = id: '/gitlab/authorize', path: '/gitlab/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsGithubConfigurePageRouteRoute = @@ -1495,7 +1617,7 @@ const secretManagerIntegrationsGithubConfigurePageRouteRoute = id: '/github/create', path: '/github/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsGithubAuthorizePageRouteRoute = @@ -1503,7 +1625,7 @@ const secretManagerIntegrationsGithubAuthorizePageRouteRoute = id: '/github/auth-mode-selection', path: '/github/auth-mode-selection', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsGcpSecretManagerConfigurePageRouteRoute = @@ -1511,7 +1633,7 @@ const secretManagerIntegrationsGcpSecretManagerConfigurePageRouteRoute = id: '/gcp-secret-manager/create', path: '/gcp-secret-manager/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsGcpSecretManagerAuthorizePageRouteRoute = @@ -1519,7 +1641,7 @@ const secretManagerIntegrationsGcpSecretManagerAuthorizePageRouteRoute = id: '/gcp-secret-manager/authorize', path: '/gcp-secret-manager/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsFlyioConfigurePageRouteRoute = @@ -1527,7 +1649,7 @@ const secretManagerIntegrationsFlyioConfigurePageRouteRoute = id: '/flyio/create', path: '/flyio/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsFlyioAuthorizePageRouteRoute = @@ -1535,7 +1657,7 @@ const secretManagerIntegrationsFlyioAuthorizePageRouteRoute = id: '/flyio/authorize', path: '/flyio/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsDigitalOceanAppPlatformConfigurePageRouteRoute = @@ -1544,7 +1666,7 @@ const secretManagerIntegrationsDigitalOceanAppPlatformConfigurePageRouteRoute = id: '/digital-ocean-app-platform/create', path: '/digital-ocean-app-platform/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any, ) @@ -1554,7 +1676,7 @@ const secretManagerIntegrationsDigitalOceanAppPlatformAuthorizePageRouteRoute = id: '/digital-ocean-app-platform/authorize', path: '/digital-ocean-app-platform/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any, ) @@ -1563,7 +1685,7 @@ const secretManagerIntegrationsDatabricksConfigurePageRouteRoute = id: '/databricks/create', path: '/databricks/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsDatabricksAuthorizePageRouteRoute = @@ -1571,7 +1693,7 @@ const secretManagerIntegrationsDatabricksAuthorizePageRouteRoute = id: '/databricks/authorize', path: '/databricks/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsCodefreshConfigurePageRouteRoute = @@ -1579,7 +1701,7 @@ const secretManagerIntegrationsCodefreshConfigurePageRouteRoute = id: '/codefresh/create', path: '/codefresh/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsCodefreshAuthorizePageRouteRoute = @@ -1587,7 +1709,7 @@ const secretManagerIntegrationsCodefreshAuthorizePageRouteRoute = id: '/codefresh/authorize', path: '/codefresh/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsCloudflareWorkersConfigurePageRouteRoute = @@ -1595,7 +1717,7 @@ const secretManagerIntegrationsCloudflareWorkersConfigurePageRouteRoute = id: '/cloudflare-workers/create', path: '/cloudflare-workers/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsCloudflareWorkersAuthorizePageRouteRoute = @@ -1603,7 +1725,7 @@ const secretManagerIntegrationsCloudflareWorkersAuthorizePageRouteRoute = id: '/cloudflare-workers/authorize', path: '/cloudflare-workers/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsCloudflarePagesConfigurePageRouteRoute = @@ -1611,7 +1733,7 @@ const secretManagerIntegrationsCloudflarePagesConfigurePageRouteRoute = id: '/cloudflare-pages/create', path: '/cloudflare-pages/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsCloudflarePagesAuthorizePageRouteRoute = @@ -1619,7 +1741,7 @@ const secretManagerIntegrationsCloudflarePagesAuthorizePageRouteRoute = id: '/cloudflare-pages/authorize', path: '/cloudflare-pages/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsCloud66ConfigurePageRouteRoute = @@ -1627,7 +1749,7 @@ const secretManagerIntegrationsCloud66ConfigurePageRouteRoute = id: '/cloud-66/create', path: '/cloud-66/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsCloud66AuthorizePageRouteRoute = @@ -1635,7 +1757,7 @@ const secretManagerIntegrationsCloud66AuthorizePageRouteRoute = id: '/cloud-66/authorize', path: '/cloud-66/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsCircleCIConfigurePageRouteRoute = @@ -1643,7 +1765,7 @@ const secretManagerIntegrationsCircleCIConfigurePageRouteRoute = id: '/circleci/create', path: '/circleci/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsCircleCIAuthorizePageRouteRoute = @@ -1651,7 +1773,7 @@ const secretManagerIntegrationsCircleCIAuthorizePageRouteRoute = id: '/circleci/authorize', path: '/circleci/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsChecklyConfigurePageRouteRoute = @@ -1659,7 +1781,7 @@ const secretManagerIntegrationsChecklyConfigurePageRouteRoute = id: '/checkly/create', path: '/checkly/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsChecklyAuthorizePageRouteRoute = @@ -1667,7 +1789,7 @@ const secretManagerIntegrationsChecklyAuthorizePageRouteRoute = id: '/checkly/authorize', path: '/checkly/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsBitbucketConfigurePageRouteRoute = @@ -1675,7 +1797,7 @@ const secretManagerIntegrationsBitbucketConfigurePageRouteRoute = id: '/bitbucket/create', path: '/bitbucket/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsAzureKeyVaultConfigurePageRouteRoute = @@ -1683,7 +1805,7 @@ const secretManagerIntegrationsAzureKeyVaultConfigurePageRouteRoute = id: '/azure-key-vault/create', path: '/azure-key-vault/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteRoute = @@ -1691,7 +1813,7 @@ const secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteRoute = id: '/azure-key-vault/authorize', path: '/azure-key-vault/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsAzureDevopsConfigurePageRouteRoute = @@ -1699,7 +1821,7 @@ const secretManagerIntegrationsAzureDevopsConfigurePageRouteRoute = id: '/azure-devops/create', path: '/azure-devops/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsAzureDevopsAuthorizePageRouteRoute = @@ -1707,7 +1829,7 @@ const secretManagerIntegrationsAzureDevopsAuthorizePageRouteRoute = id: '/azure-devops/authorize', path: '/azure-devops/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteRoute = @@ -1716,7 +1838,7 @@ const secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteRoute = id: '/azure-app-configuration/create', path: '/azure-app-configuration/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any, ) @@ -1725,7 +1847,7 @@ const secretManagerIntegrationsAwsSecretManagerConfigurePageRouteRoute = id: '/aws-secret-manager/create', path: '/aws-secret-manager/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsAwsSecretManagerAuthorizePageRouteRoute = @@ -1733,7 +1855,7 @@ const secretManagerIntegrationsAwsSecretManagerAuthorizePageRouteRoute = id: '/aws-secret-manager/authorize', path: '/aws-secret-manager/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsAwsParameterStoreConfigurePageRouteRoute = @@ -1741,7 +1863,7 @@ const secretManagerIntegrationsAwsParameterStoreConfigurePageRouteRoute = id: '/aws-parameter-store/create', path: '/aws-parameter-store/create', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsAwsParameterStoreAuthorizePageRouteRoute = @@ -1749,16 +1871,16 @@ const secretManagerIntegrationsAwsParameterStoreAuthorizePageRouteRoute = id: '/aws-parameter-store/authorize', path: '/aws-parameter-store/authorize', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRoute = - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdImport.update( +const AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRoute = + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdImport.update( { id: '/$commitId', path: '/$commitId', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRoute, } as any, ) @@ -1767,7 +1889,7 @@ const secretManagerIntegrationsVercelOauthCallbackPageRouteRoute = id: '/vercel/oauth2/callback', path: '/vercel/oauth2/callback', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerSecretSyncDetailsByIDPageRouteRoute = @@ -1775,7 +1897,7 @@ const secretManagerSecretSyncDetailsByIDPageRouteRoute = id: '/secret-syncs/$destination/$syncId', path: '/secret-syncs/$destination/$syncId', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsNetlifyOauthCallbackPageRouteRoute = @@ -1783,7 +1905,7 @@ const secretManagerIntegrationsNetlifyOauthCallbackPageRouteRoute = id: '/netlify/oauth2/callback', path: '/netlify/oauth2/callback', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsHerokuOauthCallbackPageRouteRoute = @@ -1791,7 +1913,7 @@ const secretManagerIntegrationsHerokuOauthCallbackPageRouteRoute = id: '/heroku/oauth2/callback', path: '/heroku/oauth2/callback', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsGitlabOauthCallbackPageRouteRoute = @@ -1799,7 +1921,7 @@ const secretManagerIntegrationsGitlabOauthCallbackPageRouteRoute = id: '/gitlab/oauth2/callback', path: '/gitlab/oauth2/callback', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsGithubOauthCallbackPageRouteRoute = @@ -1807,7 +1929,7 @@ const secretManagerIntegrationsGithubOauthCallbackPageRouteRoute = id: '/github/oauth2/callback', path: '/github/oauth2/callback', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsGcpSecretManagerOauthCallbackPageRouteRoute = @@ -1815,7 +1937,7 @@ const secretManagerIntegrationsGcpSecretManagerOauthCallbackPageRouteRoute = id: '/gcp-secret-manager/oauth2/callback', path: '/gcp-secret-manager/oauth2/callback', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsBitbucketOauthCallbackPageRouteRoute = @@ -1823,7 +1945,7 @@ const secretManagerIntegrationsBitbucketOauthCallbackPageRouteRoute = id: '/bitbucket/oauth2/callback', path: '/bitbucket/oauth2/callback', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsAzureKeyVaultOauthCallbackPageRouteRoute = @@ -1831,7 +1953,7 @@ const secretManagerIntegrationsAzureKeyVaultOauthCallbackPageRouteRoute = id: '/azure-key-vault/oauth2/callback', path: '/azure-key-vault/oauth2/callback', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any) const secretManagerIntegrationsAzureAppConfigurationOauthCallbackPageRouteRoute = @@ -1840,7 +1962,7 @@ const secretManagerIntegrationsAzureAppConfigurationOauthCallbackPageRouteRoute id: '/azure-app-configuration/oauth2/callback', path: '/azure-app-configuration/oauth2/callback', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, } as any, ) @@ -1849,7 +1971,7 @@ const secretManagerCommitsPageRouteRoute = id: '/', path: '/', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRoute, } as any) const secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteRoute = @@ -1857,7 +1979,7 @@ const secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteRoute = id: '/restore', path: '/restore', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRoute, } as any) const secretManagerCommitDetailsPageRouteRoute = @@ -1865,7 +1987,7 @@ const secretManagerCommitDetailsPageRouteRoute = id: '/', path: '/', getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRoute, } as any) // Populate the FileRoutesByPath interface @@ -2096,6 +2218,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof authProviderSuccessPageRouteImport parentRoute: typeof RestrictLoginSignupLoginImport } + '/_authenticate/_inject-org-details/_org-layout/integrations': { + id: '/_authenticate/_inject-org-details/_org-layout/integrations' + path: '/integrations' + fullPath: '/integrations' + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport + parentRoute: typeof organizationLayoutImport + } '/_authenticate/_inject-org-details/_org-layout/organization': { id: '/_authenticate/_inject-org-details/_org-layout/organization' path: '/organization' @@ -2215,13 +2344,6 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsImport parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId' - path: '/projects/$projectId' - fullPath: '/projects/$projectId' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdImport - parentRoute: typeof organizationLayoutImport - } '/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId': { id: '/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId' path: '/secret-manager/$projectId' @@ -2313,12 +2435,40 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof adminUserIdentitiesResourcesPageRouteImport parentRoute: typeof adminLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout' - path: '' - fullPath: '/projects/$projectId' - preLoaderRoute: typeof projectLayoutImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdImport + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId' + path: '/projects/cert-management/$projectId' + fullPath: '/projects/cert-management/$projectId' + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdImport + parentRoute: typeof organizationLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId' + path: '/projects/kms/$projectId' + fullPath: '/projects/kms/$projectId' + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsKmsProjectIdImport + parentRoute: typeof organizationLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId' + path: '/projects/secret-management/$projectId' + fullPath: '/projects/secret-management/$projectId' + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdImport + parentRoute: typeof organizationLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId' + path: '/projects/secret-scanning/$projectId' + fullPath: '/projects/secret-scanning/$projectId' + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdImport + parentRoute: typeof organizationLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId' + path: '/projects/ssh/$projectId' + fullPath: '/projects/ssh/$projectId' + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSshProjectIdImport + parentRoute: typeof organizationLayoutImport } '/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId/approval': { id: '/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId/approval' @@ -2334,54 +2484,103 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof organizationSettingsPageOauthCallbackPageRouteImport parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout' + '/_authenticate/_inject-org-details/_org-layout/integrations/azure-app-configuration/oauth2/callback': { + id: '/_authenticate/_inject-org-details/_org-layout/integrations/azure-app-configuration/oauth2/callback' + path: '/azure-app-configuration/oauth2/callback' + fullPath: '/integrations/azure-app-configuration/oauth2/callback' + preLoaderRoute: typeof secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/integrations/azure-key-vault/oauth2/callback': { + id: '/_authenticate/_inject-org-details/_org-layout/integrations/azure-key-vault/oauth2/callback' + path: '/azure-key-vault/oauth2/callback' + fullPath: '/integrations/azure-key-vault/oauth2/callback' + preLoaderRoute: typeof secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/integrations/bitbucket/oauth2/callback': { + id: '/_authenticate/_inject-org-details/_org-layout/integrations/bitbucket/oauth2/callback' + path: '/bitbucket/oauth2/callback' + fullPath: '/integrations/bitbucket/oauth2/callback' + preLoaderRoute: typeof secretManagerIntegrationsRouteBitbucketOauthRedirectImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/integrations/gcp-secret-manager/oauth2/callback': { + id: '/_authenticate/_inject-org-details/_org-layout/integrations/gcp-secret-manager/oauth2/callback' + path: '/gcp-secret-manager/oauth2/callback' + fullPath: '/integrations/gcp-secret-manager/oauth2/callback' + preLoaderRoute: typeof secretManagerIntegrationsRouteGcpOauthRedirectImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/integrations/github/oauth2/callback': { + id: '/_authenticate/_inject-org-details/_org-layout/integrations/github/oauth2/callback' + path: '/github/oauth2/callback' + fullPath: '/integrations/github/oauth2/callback' + preLoaderRoute: typeof secretManagerIntegrationsRouteGithubOauthRedirectImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/integrations/gitlab/oauth2/callback': { + id: '/_authenticate/_inject-org-details/_org-layout/integrations/gitlab/oauth2/callback' + path: '/gitlab/oauth2/callback' + fullPath: '/integrations/gitlab/oauth2/callback' + preLoaderRoute: typeof secretManagerIntegrationsRouteGitlabOauthRedirectImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/integrations/heroku/oauth2/callback': { + id: '/_authenticate/_inject-org-details/_org-layout/integrations/heroku/oauth2/callback' + path: '/heroku/oauth2/callback' + fullPath: '/integrations/heroku/oauth2/callback' + preLoaderRoute: typeof secretManagerIntegrationsRouteHerokuOauthRedirectImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/integrations/netlify/oauth2/callback': { + id: '/_authenticate/_inject-org-details/_org-layout/integrations/netlify/oauth2/callback' + path: '/netlify/oauth2/callback' + fullPath: '/integrations/netlify/oauth2/callback' + preLoaderRoute: typeof secretManagerIntegrationsRouteNetlifyOauthRedirectImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/integrations/vercel/oauth2/callback': { + id: '/_authenticate/_inject-org-details/_org-layout/integrations/vercel/oauth2/callback' + path: '/vercel/oauth2/callback' + fullPath: '/integrations/vercel/oauth2/callback' + preLoaderRoute: typeof secretManagerIntegrationsRouteVercelOauthRedirectImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout' path: '' - fullPath: '/projects/$projectId' - preLoaderRoute: typeof projectLayoutGeneralImport - parentRoute: typeof projectLayoutImport + fullPath: '/projects/cert-management/$projectId' + preLoaderRoute: typeof certManagerLayoutImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager' - path: '/cert-manager' - fullPath: '/projects/$projectId/cert-manager' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerImport - parentRoute: typeof projectLayoutImport + '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout' + path: '' + fullPath: '/projects/kms/$projectId' + preLoaderRoute: typeof kmsLayoutImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsKmsProjectIdImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations' - path: '/integrations' - fullPath: '/projects/$projectId/integrations' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsImport - parentRoute: typeof projectLayoutImport + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout' + path: '' + fullPath: '/projects/secret-management/$projectId' + preLoaderRoute: typeof secretManagerLayoutImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms' - path: '/kms' - fullPath: '/projects/$projectId/kms' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutKmsImport - parentRoute: typeof projectLayoutImport + '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout' + path: '' + fullPath: '/projects/secret-scanning/$projectId' + preLoaderRoute: typeof secretScanningLayoutImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager' - path: '/secret-manager' - fullPath: '/projects/$projectId/secret-manager' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerImport - parentRoute: typeof projectLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning' - path: '/secret-scanning' - fullPath: '/projects/$projectId/secret-scanning' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningImport - parentRoute: typeof projectLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh' - path: '/ssh' - fullPath: '/projects/$projectId/ssh' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSshImport - parentRoute: typeof projectLayoutImport + '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout' + path: '' + fullPath: '/projects/ssh/$projectId' + preLoaderRoute: typeof sshLayoutImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSshProjectIdImport } '/_authenticate/_inject-org-details/_org-layout/organization/app-connections/$appConnection/oauth/callback': { id: '/_authenticate/_inject-org-details/_org-layout/organization/app-connections/$appConnection/oauth/callback' @@ -2390,956 +2589,1030 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof organizationAppConnectionsOauthCallbackPageRouteImport parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/access-management': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/access-management' - path: '/access-management' - fullPath: '/projects/$projectId/access-management' - preLoaderRoute: typeof projectAccessControlPageRouteImport - parentRoute: typeof projectLayoutGeneralImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/settings': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/settings' - path: '/settings' - fullPath: '/projects/$projectId/settings' - preLoaderRoute: typeof projectSettingsPageRouteImport - parentRoute: typeof projectLayoutGeneralImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout' - path: '' - fullPath: '/projects/$projectId/cert-manager' - preLoaderRoute: typeof certManagerLayoutImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout' - path: '' - fullPath: '/projects/$projectId/kms' - preLoaderRoute: typeof kmsLayoutImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutKmsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout' - path: '' - fullPath: '/projects/$projectId/secret-manager' - preLoaderRoute: typeof secretManagerLayoutImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout' - path: '' - fullPath: '/projects/$projectId/secret-scanning' - preLoaderRoute: typeof secretScanningLayoutImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout' - path: '' - fullPath: '/projects/$projectId/ssh' - preLoaderRoute: typeof sshLayoutImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSshImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/groups/$groupId': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/groups/$groupId' - path: '/groups/$groupId' - fullPath: '/projects/$projectId/groups/$groupId' - preLoaderRoute: typeof projectGroupDetailsByIDPageRouteImport - parentRoute: typeof projectLayoutGeneralImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/identities/$identityId': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/identities/$identityId' - path: '/identities/$identityId' - fullPath: '/projects/$projectId/identities/$identityId' - preLoaderRoute: typeof projectIdentityDetailsByIDPageRouteImport - parentRoute: typeof projectLayoutGeneralImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/members/$membershipId': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/members/$membershipId' - path: '/members/$membershipId' - fullPath: '/projects/$projectId/members/$membershipId' - preLoaderRoute: typeof projectMemberDetailsByIDPageRouteImport - parentRoute: typeof projectLayoutGeneralImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/roles/$roleSlug': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/roles/$roleSlug' - path: '/roles/$roleSlug' - fullPath: '/projects/$projectId/roles/$roleSlug' - preLoaderRoute: typeof projectRoleDetailsBySlugPageRouteImport - parentRoute: typeof projectLayoutGeneralImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/alerting': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/alerting' + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/alerting': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/alerting' path: '/alerting' - fullPath: '/projects/$projectId/cert-manager/alerting' + fullPath: '/projects/cert-management/$projectId/alerting' preLoaderRoute: typeof certManagerAlertingPageRouteImport parentRoute: typeof certManagerLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificate-authorities': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificate-authorities' + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificate-authorities': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificate-authorities' path: '/certificate-authorities' - fullPath: '/projects/$projectId/cert-manager/certificate-authorities' + fullPath: '/projects/cert-management/$projectId/certificate-authorities' preLoaderRoute: typeof certManagerCertificateAuthoritiesPageRouteImport parentRoute: typeof certManagerLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificates': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificates' + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificates': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificates' path: '/certificates' - fullPath: '/projects/$projectId/cert-manager/certificates' + fullPath: '/projects/cert-management/$projectId/certificates' preLoaderRoute: typeof certManagerCertificatesPageRouteImport parentRoute: typeof certManagerLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/settings': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/settings' + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/settings': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/settings' path: '/settings' - fullPath: '/projects/$projectId/cert-manager/settings' + fullPath: '/projects/cert-management/$projectId/settings' preLoaderRoute: typeof certManagerSettingsPageRouteImport parentRoute: typeof certManagerLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout/kmip': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout/kmip' + '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/kmip': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/kmip' path: '/kmip' - fullPath: '/projects/$projectId/kms/kmip' + fullPath: '/projects/kms/$projectId/kmip' preLoaderRoute: typeof kmsKmipPageRouteImport parentRoute: typeof kmsLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout/overview': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout/overview' + '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/overview': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/overview' path: '/overview' - fullPath: '/projects/$projectId/kms/overview' + fullPath: '/projects/kms/$projectId/overview' preLoaderRoute: typeof kmsOverviewPageRouteImport parentRoute: typeof kmsLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout/settings': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout/settings' + '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/settings': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/settings' path: '/settings' - fullPath: '/projects/$projectId/kms/settings' + fullPath: '/projects/kms/$projectId/settings' preLoaderRoute: typeof kmsSettingsPageRouteImport parentRoute: typeof kmsLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/allowlist': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/allowlist' + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/allowlist': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/allowlist' path: '/allowlist' - fullPath: '/projects/$projectId/secret-manager/allowlist' + fullPath: '/projects/secret-management/$projectId/allowlist' preLoaderRoute: typeof secretManagerIPAllowlistPageRouteImport parentRoute: typeof secretManagerLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/approval': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/approval' + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/approval': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/approval' path: '/approval' - fullPath: '/projects/$projectId/secret-manager/approval' + fullPath: '/projects/secret-management/$projectId/approval' preLoaderRoute: typeof secretManagerSecretApprovalsPageRouteImport parentRoute: typeof secretManagerLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/overview': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/overview' + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/overview': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/overview' path: '/overview' - fullPath: '/projects/$projectId/secret-manager/overview' + fullPath: '/projects/secret-management/$projectId/overview' preLoaderRoute: typeof secretManagerOverviewPageRouteImport parentRoute: typeof secretManagerLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/secret-rotation': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/secret-rotation' + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/secret-rotation': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/secret-rotation' path: '/secret-rotation' - fullPath: '/projects/$projectId/secret-manager/secret-rotation' + fullPath: '/projects/secret-management/$projectId/secret-rotation' preLoaderRoute: typeof secretManagerSecretRotationPageRouteImport parentRoute: typeof secretManagerLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/settings': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/settings' + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/settings': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/settings' path: '/settings' - fullPath: '/projects/$projectId/secret-manager/settings' + fullPath: '/projects/secret-management/$projectId/settings' preLoaderRoute: typeof secretManagerSettingsPageRouteImport parentRoute: typeof secretManagerLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/findings': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/findings' + '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/findings': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/findings' path: '/findings' - fullPath: '/projects/$projectId/secret-scanning/findings' + fullPath: '/projects/secret-scanning/$projectId/findings' preLoaderRoute: typeof secretScanningSecretScanningFindingsPageRouteImport parentRoute: typeof secretScanningLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/settings': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/settings' + '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/settings': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/settings' path: '/settings' - fullPath: '/projects/$projectId/secret-scanning/settings' + fullPath: '/projects/secret-scanning/$projectId/settings' preLoaderRoute: typeof secretScanningSettingsPageRouteImport parentRoute: typeof secretScanningLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/cas': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/cas' + '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/cas': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/cas' path: '/cas' - fullPath: '/projects/$projectId/ssh/cas' + fullPath: '/projects/ssh/$projectId/cas' preLoaderRoute: typeof sshSshCasPageRouteImport parentRoute: typeof sshLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/certificates': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/certificates' + '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/certificates': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/certificates' path: '/certificates' - fullPath: '/projects/$projectId/ssh/certificates' + fullPath: '/projects/ssh/$projectId/certificates' preLoaderRoute: typeof sshSshCertsPageRouteImport parentRoute: typeof sshLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/overview': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/overview' + '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/overview': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/overview' path: '/overview' - fullPath: '/projects/$projectId/ssh/overview' + fullPath: '/projects/ssh/$projectId/overview' preLoaderRoute: typeof sshSshHostsPageRouteImport parentRoute: typeof sshLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/settings': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/settings' + '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/settings': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/settings' path: '/settings' - fullPath: '/projects/$projectId/ssh/settings' + fullPath: '/projects/ssh/$projectId/settings' preLoaderRoute: typeof sshSettingsPageRouteImport parentRoute: typeof sshLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificate-templates': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificate-templates' + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/access-management': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/access-management' + path: '/access-management' + fullPath: '/projects/cert-management/$projectId/access-management' + preLoaderRoute: typeof projectAccessControlPageRouteCertManagerImport + parentRoute: typeof certManagerLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates' path: '/certificate-templates' - fullPath: '/projects/$projectId/cert-manager/certificate-templates' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutCertificateTemplatesImport + fullPath: '/projects/cert-management/$projectId/certificate-templates' + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesImport parentRoute: typeof certManagerLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/subscribers': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/subscribers' + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/subscribers': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/subscribers' path: '/subscribers' - fullPath: '/projects/$projectId/cert-manager/subscribers' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutSubscribersImport + fullPath: '/projects/cert-management/$projectId/subscribers' + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutSubscribersImport parentRoute: typeof certManagerLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations' - path: '/integrations' - fullPath: '/projects/$projectId/secret-manager/integrations' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport + '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/access-management': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/access-management' + path: '/access-management' + fullPath: '/projects/kms/$projectId/access-management' + preLoaderRoute: typeof projectAccessControlPageRouteKmsImport + parentRoute: typeof kmsLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/access-management': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/access-management' + path: '/access-management' + fullPath: '/projects/secret-management/$projectId/access-management' + preLoaderRoute: typeof projectAccessControlPageRouteSecretManagerImport parentRoute: typeof secretManagerLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/data-sources': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/data-sources' - path: '/data-sources' - fullPath: '/projects/$projectId/secret-scanning/data-sources' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningSecretScanningLayoutDataSourcesImport + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations' + path: '/integrations' + fullPath: '/projects/secret-management/$projectId/integrations' + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + parentRoute: typeof secretManagerLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/access-management': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/access-management' + path: '/access-management' + fullPath: '/projects/secret-scanning/$projectId/access-management' + preLoaderRoute: typeof projectAccessControlPageRouteSecretScanningImport parentRoute: typeof secretScanningLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificate-templates/': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificate-templates/' + '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources' + path: '/data-sources' + fullPath: '/projects/secret-scanning/$projectId/data-sources' + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesImport + parentRoute: typeof secretScanningLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/access-management': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/access-management' + path: '/access-management' + fullPath: '/projects/ssh/$projectId/access-management' + preLoaderRoute: typeof projectAccessControlPageRouteSshImport + parentRoute: typeof sshLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates/': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates/' path: '/' - fullPath: '/projects/$projectId/cert-manager/certificate-templates/' + fullPath: '/projects/cert-management/$projectId/certificate-templates/' preLoaderRoute: typeof certManagerPkiTemplateListPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutCertificateTemplatesImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/subscribers/': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/subscribers/' + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/subscribers/': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/subscribers/' path: '/' - fullPath: '/projects/$projectId/cert-manager/subscribers/' + fullPath: '/projects/cert-management/$projectId/subscribers/' preLoaderRoute: typeof certManagerPkiSubscribersPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutSubscribersImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutSubscribersImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/' + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/' path: '/' - fullPath: '/projects/$projectId/secret-manager/integrations/' + fullPath: '/projects/secret-management/$projectId/integrations/' preLoaderRoute: typeof secretManagerIntegrationsListPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/data-sources/': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/data-sources/' + '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/' path: '/' - fullPath: '/projects/$projectId/secret-scanning/data-sources/' + fullPath: '/projects/secret-scanning/$projectId/data-sources/' preLoaderRoute: typeof secretScanningSecretScanningDataSourcesPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningSecretScanningLayoutDataSourcesImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/ca/$caName': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/ca/$caName' + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/ca/$caName': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/ca/$caName' path: '/ca/$caName' - fullPath: '/projects/$projectId/cert-manager/ca/$caName' + fullPath: '/projects/cert-management/$projectId/ca/$caName' preLoaderRoute: typeof certManagerCertAuthDetailsByIDPageRouteImport parentRoute: typeof certManagerLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/subscribers/$subscriberName': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/subscribers/$subscriberName' + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/subscribers/$subscriberName': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/subscribers/$subscriberName' path: '/$subscriberName' - fullPath: '/projects/$projectId/cert-manager/subscribers/$subscriberName' + fullPath: '/projects/cert-management/$projectId/subscribers/$subscriberName' preLoaderRoute: typeof certManagerPkiSubscriberDetailsByIDPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutSubscribersImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutSubscribersImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/$integrationId': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/$integrationId' + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/$integrationId': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/$integrationId' path: '/$integrationId' - fullPath: '/projects/$projectId/secret-manager/integrations/$integrationId' + fullPath: '/projects/secret-management/$projectId/integrations/$integrationId' preLoaderRoute: typeof secretManagerIntegrationsDetailsByIDPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/select-integration-auth': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/select-integration-auth' + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/select-integration-auth': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/select-integration-auth' path: '/select-integration-auth' - fullPath: '/projects/$projectId/secret-manager/integrations/select-integration-auth' + fullPath: '/projects/secret-management/$projectId/integrations/select-integration-auth' preLoaderRoute: typeof secretManagerIntegrationsSelectIntegrationAuthPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/secrets/$envSlug': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/secrets/$envSlug' + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/secrets/$envSlug': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/secrets/$envSlug' path: '/secrets/$envSlug' - fullPath: '/projects/$projectId/secret-manager/secrets/$envSlug' + fullPath: '/projects/secret-management/$projectId/secrets/$envSlug' preLoaderRoute: typeof secretManagerSecretDashboardPageRouteImport parentRoute: typeof secretManagerLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/ca/$caId': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/ca/$caId' + '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/ca/$caId': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/ca/$caId' path: '/ca/$caId' - fullPath: '/projects/$projectId/ssh/ca/$caId' + fullPath: '/projects/ssh/$projectId/ca/$caId' preLoaderRoute: typeof sshSshCaByIDPageRouteImport parentRoute: typeof sshLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/ssh-host-groups/$sshHostGroupId': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/ssh-host-groups/$sshHostGroupId' + '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/ssh-host-groups/$sshHostGroupId': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/ssh-host-groups/$sshHostGroupId' path: '/ssh-host-groups/$sshHostGroupId' - fullPath: '/projects/$projectId/ssh/ssh-host-groups/$sshHostGroupId' + fullPath: '/projects/ssh/$projectId/ssh-host-groups/$sshHostGroupId' preLoaderRoute: typeof sshSshHostGroupDetailsByIDPageRouteImport parentRoute: typeof sshLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/pki-collections/$collectionId': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/pki-collections/$collectionId' + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/groups/$groupId': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/groups/$groupId' + path: '/groups/$groupId' + fullPath: '/projects/cert-management/$projectId/groups/$groupId' + preLoaderRoute: typeof projectGroupDetailsByIDPageRouteCertManagerImport + parentRoute: typeof certManagerLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/identities/$identityId': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/identities/$identityId' + path: '/identities/$identityId' + fullPath: '/projects/cert-management/$projectId/identities/$identityId' + preLoaderRoute: typeof projectIdentityDetailsByIDPageRouteCertManagerImport + parentRoute: typeof certManagerLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/members/$membershipId': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/members/$membershipId' + path: '/members/$membershipId' + fullPath: '/projects/cert-management/$projectId/members/$membershipId' + preLoaderRoute: typeof projectMemberDetailsByIDPageRouteCertManagerImport + parentRoute: typeof certManagerLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/pki-collections/$collectionId': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/pki-collections/$collectionId' path: '/pki-collections/$collectionId' - fullPath: '/projects/$projectId/cert-manager/pki-collections/$collectionId' + fullPath: '/projects/cert-management/$projectId/pki-collections/$collectionId' preLoaderRoute: typeof certManagerPkiCollectionDetailsByIDPageRoutesImport parentRoute: typeof certManagerLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/azure-app-configuration/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/azure-app-configuration/oauth2/callback' - path: '/azure-app-configuration/oauth2/callback' - fullPath: '/projects/$projectId/integrations/azure-app-configuration/oauth2/callback' - preLoaderRoute: typeof secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/azure-key-vault/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/azure-key-vault/oauth2/callback' - path: '/azure-key-vault/oauth2/callback' - fullPath: '/projects/$projectId/integrations/azure-key-vault/oauth2/callback' - preLoaderRoute: typeof secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/bitbucket/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/bitbucket/oauth2/callback' - path: '/bitbucket/oauth2/callback' - fullPath: '/projects/$projectId/integrations/bitbucket/oauth2/callback' - preLoaderRoute: typeof secretManagerIntegrationsRouteBitbucketOauthRedirectImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/gcp-secret-manager/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/gcp-secret-manager/oauth2/callback' - path: '/gcp-secret-manager/oauth2/callback' - fullPath: '/projects/$projectId/integrations/gcp-secret-manager/oauth2/callback' - preLoaderRoute: typeof secretManagerIntegrationsRouteGcpOauthRedirectImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/github/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/github/oauth2/callback' - path: '/github/oauth2/callback' - fullPath: '/projects/$projectId/integrations/github/oauth2/callback' - preLoaderRoute: typeof secretManagerIntegrationsRouteGithubOauthRedirectImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/gitlab/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/gitlab/oauth2/callback' - path: '/gitlab/oauth2/callback' - fullPath: '/projects/$projectId/integrations/gitlab/oauth2/callback' - preLoaderRoute: typeof secretManagerIntegrationsRouteGitlabOauthRedirectImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/heroku/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/heroku/oauth2/callback' - path: '/heroku/oauth2/callback' - fullPath: '/projects/$projectId/integrations/heroku/oauth2/callback' - preLoaderRoute: typeof secretManagerIntegrationsRouteHerokuOauthRedirectImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/netlify/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/netlify/oauth2/callback' - path: '/netlify/oauth2/callback' - fullPath: '/projects/$projectId/integrations/netlify/oauth2/callback' - preLoaderRoute: typeof secretManagerIntegrationsRouteNetlifyOauthRedirectImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/vercel/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/vercel/oauth2/callback' - path: '/vercel/oauth2/callback' - fullPath: '/projects/$projectId/integrations/vercel/oauth2/callback' - preLoaderRoute: typeof secretManagerIntegrationsRouteVercelOauthRedirectImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-parameter-store/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-parameter-store/authorize' - path: '/aws-parameter-store/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/aws-parameter-store/authorize' - preLoaderRoute: typeof secretManagerIntegrationsAwsParameterStoreAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-parameter-store/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-parameter-store/create' - path: '/aws-parameter-store/create' - fullPath: '/projects/$projectId/secret-manager/integrations/aws-parameter-store/create' - preLoaderRoute: typeof secretManagerIntegrationsAwsParameterStoreConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-secret-manager/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-secret-manager/authorize' - path: '/aws-secret-manager/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/aws-secret-manager/authorize' - preLoaderRoute: typeof secretManagerIntegrationsAwsSecretManagerAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-secret-manager/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-secret-manager/create' - path: '/aws-secret-manager/create' - fullPath: '/projects/$projectId/secret-manager/integrations/aws-secret-manager/create' - preLoaderRoute: typeof secretManagerIntegrationsAwsSecretManagerConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-app-configuration/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-app-configuration/create' - path: '/azure-app-configuration/create' - fullPath: '/projects/$projectId/secret-manager/integrations/azure-app-configuration/create' - preLoaderRoute: typeof secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-devops/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-devops/authorize' - path: '/azure-devops/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/azure-devops/authorize' - preLoaderRoute: typeof secretManagerIntegrationsAzureDevopsAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-devops/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-devops/create' - path: '/azure-devops/create' - fullPath: '/projects/$projectId/secret-manager/integrations/azure-devops/create' - preLoaderRoute: typeof secretManagerIntegrationsAzureDevopsConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-key-vault/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-key-vault/authorize' - path: '/azure-key-vault/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/azure-key-vault/authorize' - preLoaderRoute: typeof secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-key-vault/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-key-vault/create' - path: '/azure-key-vault/create' - fullPath: '/projects/$projectId/secret-manager/integrations/azure-key-vault/create' - preLoaderRoute: typeof secretManagerIntegrationsAzureKeyVaultConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/bitbucket/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/bitbucket/create' - path: '/bitbucket/create' - fullPath: '/projects/$projectId/secret-manager/integrations/bitbucket/create' - preLoaderRoute: typeof secretManagerIntegrationsBitbucketConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/checkly/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/checkly/authorize' - path: '/checkly/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/checkly/authorize' - preLoaderRoute: typeof secretManagerIntegrationsChecklyAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/checkly/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/checkly/create' - path: '/checkly/create' - fullPath: '/projects/$projectId/secret-manager/integrations/checkly/create' - preLoaderRoute: typeof secretManagerIntegrationsChecklyConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/circleci/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/circleci/authorize' - path: '/circleci/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/circleci/authorize' - preLoaderRoute: typeof secretManagerIntegrationsCircleCIAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/circleci/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/circleci/create' - path: '/circleci/create' - fullPath: '/projects/$projectId/secret-manager/integrations/circleci/create' - preLoaderRoute: typeof secretManagerIntegrationsCircleCIConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloud-66/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloud-66/authorize' - path: '/cloud-66/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/cloud-66/authorize' - preLoaderRoute: typeof secretManagerIntegrationsCloud66AuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloud-66/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloud-66/create' - path: '/cloud-66/create' - fullPath: '/projects/$projectId/secret-manager/integrations/cloud-66/create' - preLoaderRoute: typeof secretManagerIntegrationsCloud66ConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-pages/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-pages/authorize' - path: '/cloudflare-pages/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/cloudflare-pages/authorize' - preLoaderRoute: typeof secretManagerIntegrationsCloudflarePagesAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-pages/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-pages/create' - path: '/cloudflare-pages/create' - fullPath: '/projects/$projectId/secret-manager/integrations/cloudflare-pages/create' - preLoaderRoute: typeof secretManagerIntegrationsCloudflarePagesConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-workers/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-workers/authorize' - path: '/cloudflare-workers/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/cloudflare-workers/authorize' - preLoaderRoute: typeof secretManagerIntegrationsCloudflareWorkersAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-workers/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-workers/create' - path: '/cloudflare-workers/create' - fullPath: '/projects/$projectId/secret-manager/integrations/cloudflare-workers/create' - preLoaderRoute: typeof secretManagerIntegrationsCloudflareWorkersConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/codefresh/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/codefresh/authorize' - path: '/codefresh/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/codefresh/authorize' - preLoaderRoute: typeof secretManagerIntegrationsCodefreshAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/codefresh/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/codefresh/create' - path: '/codefresh/create' - fullPath: '/projects/$projectId/secret-manager/integrations/codefresh/create' - preLoaderRoute: typeof secretManagerIntegrationsCodefreshConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/databricks/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/databricks/authorize' - path: '/databricks/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/databricks/authorize' - preLoaderRoute: typeof secretManagerIntegrationsDatabricksAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/databricks/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/databricks/create' - path: '/databricks/create' - fullPath: '/projects/$projectId/secret-manager/integrations/databricks/create' - preLoaderRoute: typeof secretManagerIntegrationsDatabricksConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/digital-ocean-app-platform/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/digital-ocean-app-platform/authorize' - path: '/digital-ocean-app-platform/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/digital-ocean-app-platform/authorize' - preLoaderRoute: typeof secretManagerIntegrationsDigitalOceanAppPlatformAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/digital-ocean-app-platform/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/digital-ocean-app-platform/create' - path: '/digital-ocean-app-platform/create' - fullPath: '/projects/$projectId/secret-manager/integrations/digital-ocean-app-platform/create' - preLoaderRoute: typeof secretManagerIntegrationsDigitalOceanAppPlatformConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/flyio/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/flyio/authorize' - path: '/flyio/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/flyio/authorize' - preLoaderRoute: typeof secretManagerIntegrationsFlyioAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/flyio/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/flyio/create' - path: '/flyio/create' - fullPath: '/projects/$projectId/secret-manager/integrations/flyio/create' - preLoaderRoute: typeof secretManagerIntegrationsFlyioConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gcp-secret-manager/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gcp-secret-manager/authorize' - path: '/gcp-secret-manager/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/gcp-secret-manager/authorize' - preLoaderRoute: typeof secretManagerIntegrationsGcpSecretManagerAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gcp-secret-manager/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gcp-secret-manager/create' - path: '/gcp-secret-manager/create' - fullPath: '/projects/$projectId/secret-manager/integrations/gcp-secret-manager/create' - preLoaderRoute: typeof secretManagerIntegrationsGcpSecretManagerConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/github/auth-mode-selection': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/github/auth-mode-selection' - path: '/github/auth-mode-selection' - fullPath: '/projects/$projectId/secret-manager/integrations/github/auth-mode-selection' - preLoaderRoute: typeof secretManagerIntegrationsGithubAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/github/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/github/create' - path: '/github/create' - fullPath: '/projects/$projectId/secret-manager/integrations/github/create' - preLoaderRoute: typeof secretManagerIntegrationsGithubConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gitlab/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gitlab/authorize' - path: '/gitlab/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/gitlab/authorize' - preLoaderRoute: typeof secretManagerIntegrationsGitlabAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gitlab/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gitlab/create' - path: '/gitlab/create' - fullPath: '/projects/$projectId/secret-manager/integrations/gitlab/create' - preLoaderRoute: typeof secretManagerIntegrationsGitlabConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hashicorp-vault/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hashicorp-vault/authorize' - path: '/hashicorp-vault/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/hashicorp-vault/authorize' - preLoaderRoute: typeof secretManagerIntegrationsHashicorpVaultAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hashicorp-vault/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hashicorp-vault/create' - path: '/hashicorp-vault/create' - fullPath: '/projects/$projectId/secret-manager/integrations/hashicorp-vault/create' - preLoaderRoute: typeof secretManagerIntegrationsHashicorpVaultConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hasura-cloud/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hasura-cloud/authorize' - path: '/hasura-cloud/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/hasura-cloud/authorize' - preLoaderRoute: typeof secretManagerIntegrationsHasuraCloudAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hasura-cloud/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hasura-cloud/create' - path: '/hasura-cloud/create' - fullPath: '/projects/$projectId/secret-manager/integrations/hasura-cloud/create' - preLoaderRoute: typeof secretManagerIntegrationsHasuraCloudConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/heroku/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/heroku/create' - path: '/heroku/create' - fullPath: '/projects/$projectId/secret-manager/integrations/heroku/create' - preLoaderRoute: typeof secretManagerIntegrationsHerokuConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/laravel-forge/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/laravel-forge/authorize' - path: '/laravel-forge/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/laravel-forge/authorize' - preLoaderRoute: typeof secretManagerIntegrationsLaravelForgeAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/laravel-forge/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/laravel-forge/create' - path: '/laravel-forge/create' - fullPath: '/projects/$projectId/secret-manager/integrations/laravel-forge/create' - preLoaderRoute: typeof secretManagerIntegrationsLaravelForgeConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/netlify/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/netlify/create' - path: '/netlify/create' - fullPath: '/projects/$projectId/secret-manager/integrations/netlify/create' - preLoaderRoute: typeof secretManagerIntegrationsNetlifyConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/northflank/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/northflank/authorize' - path: '/northflank/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/northflank/authorize' - preLoaderRoute: typeof secretManagerIntegrationsNorthflankAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/northflank/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/northflank/create' - path: '/northflank/create' - fullPath: '/projects/$projectId/secret-manager/integrations/northflank/create' - preLoaderRoute: typeof secretManagerIntegrationsNorthflankConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/octopus-deploy/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/octopus-deploy/authorize' - path: '/octopus-deploy/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/octopus-deploy/authorize' - preLoaderRoute: typeof secretManagerIntegrationsOctopusDeployAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/octopus-deploy/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/octopus-deploy/create' - path: '/octopus-deploy/create' - fullPath: '/projects/$projectId/secret-manager/integrations/octopus-deploy/create' - preLoaderRoute: typeof secretManagerIntegrationsOctopusDeployConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/qovery/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/qovery/authorize' - path: '/qovery/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/qovery/authorize' - preLoaderRoute: typeof secretManagerIntegrationsQoveryAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/qovery/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/qovery/create' - path: '/qovery/create' - fullPath: '/projects/$projectId/secret-manager/integrations/qovery/create' - preLoaderRoute: typeof secretManagerIntegrationsQoveryConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/railway/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/railway/authorize' - path: '/railway/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/railway/authorize' - preLoaderRoute: typeof secretManagerIntegrationsRailwayAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/railway/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/railway/create' - path: '/railway/create' - fullPath: '/projects/$projectId/secret-manager/integrations/railway/create' - preLoaderRoute: typeof secretManagerIntegrationsRailwayConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/render/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/render/authorize' - path: '/render/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/render/authorize' - preLoaderRoute: typeof secretManagerIntegrationsRenderAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/render/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/render/create' - path: '/render/create' - fullPath: '/projects/$projectId/secret-manager/integrations/render/create' - preLoaderRoute: typeof secretManagerIntegrationsRenderConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/rundeck/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/rundeck/authorize' - path: '/rundeck/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/rundeck/authorize' - preLoaderRoute: typeof secretManagerIntegrationsRundeckAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/rundeck/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/rundeck/create' - path: '/rundeck/create' - fullPath: '/projects/$projectId/secret-manager/integrations/rundeck/create' - preLoaderRoute: typeof secretManagerIntegrationsRundeckConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/supabase/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/supabase/authorize' - path: '/supabase/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/supabase/authorize' - preLoaderRoute: typeof secretManagerIntegrationsSupabaseAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/supabase/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/supabase/create' - path: '/supabase/create' - fullPath: '/projects/$projectId/secret-manager/integrations/supabase/create' - preLoaderRoute: typeof secretManagerIntegrationsSupabaseConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/teamcity/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/teamcity/authorize' - path: '/teamcity/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/teamcity/authorize' - preLoaderRoute: typeof secretManagerIntegrationsTeamcityAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/teamcity/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/teamcity/create' - path: '/teamcity/create' - fullPath: '/projects/$projectId/secret-manager/integrations/teamcity/create' - preLoaderRoute: typeof secretManagerIntegrationsTeamcityConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/terraform-cloud/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/terraform-cloud/authorize' - path: '/terraform-cloud/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/terraform-cloud/authorize' - preLoaderRoute: typeof secretManagerIntegrationsTerraformCloudAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/terraform-cloud/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/terraform-cloud/create' - path: '/terraform-cloud/create' - fullPath: '/projects/$projectId/secret-manager/integrations/terraform-cloud/create' - preLoaderRoute: typeof secretManagerIntegrationsTerraformCloudConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/travisci/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/travisci/authorize' - path: '/travisci/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/travisci/authorize' - preLoaderRoute: typeof secretManagerIntegrationsTravisCIAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/travisci/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/travisci/create' - path: '/travisci/create' - fullPath: '/projects/$projectId/secret-manager/integrations/travisci/create' - preLoaderRoute: typeof secretManagerIntegrationsTravisCIConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/vercel/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/vercel/create' - path: '/vercel/create' - fullPath: '/projects/$projectId/secret-manager/integrations/vercel/create' - preLoaderRoute: typeof secretManagerIntegrationsVercelConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/windmill/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/windmill/authorize' - path: '/windmill/authorize' - fullPath: '/projects/$projectId/secret-manager/integrations/windmill/authorize' - preLoaderRoute: typeof secretManagerIntegrationsWindmillAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/windmill/create': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/windmill/create' - path: '/windmill/create' - fullPath: '/projects/$projectId/secret-manager/integrations/windmill/create' - preLoaderRoute: typeof secretManagerIntegrationsWindmillConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/data-sources/$type/$dataSourceId': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/data-sources/$type/$dataSourceId' - path: '/$type/$dataSourceId' - fullPath: '/projects/$projectId/secret-scanning/data-sources/$type/$dataSourceId' - preLoaderRoute: typeof secretScanningSecretScanningDataSourceByIdPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningSecretScanningLayoutDataSourcesImport - } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId' - path: '/commits/$environment/$folderId' - fullPath: '/projects/$projectId/secret-manager/commits/$environment/$folderId' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdImport + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/roles/$roleSlug': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/roles/$roleSlug' + path: '/roles/$roleSlug' + fullPath: '/projects/cert-management/$projectId/roles/$roleSlug' + preLoaderRoute: typeof projectRoleDetailsBySlugPageRouteCertManagerImport + parentRoute: typeof certManagerLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/groups/$groupId': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/groups/$groupId' + path: '/groups/$groupId' + fullPath: '/projects/kms/$projectId/groups/$groupId' + preLoaderRoute: typeof projectGroupDetailsByIDPageRouteKmsImport + parentRoute: typeof kmsLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/identities/$identityId': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/identities/$identityId' + path: '/identities/$identityId' + fullPath: '/projects/kms/$projectId/identities/$identityId' + preLoaderRoute: typeof projectIdentityDetailsByIDPageRouteKmsImport + parentRoute: typeof kmsLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/members/$membershipId': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/members/$membershipId' + path: '/members/$membershipId' + fullPath: '/projects/kms/$projectId/members/$membershipId' + preLoaderRoute: typeof projectMemberDetailsByIDPageRouteKmsImport + parentRoute: typeof kmsLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/roles/$roleSlug': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/roles/$roleSlug' + path: '/roles/$roleSlug' + fullPath: '/projects/kms/$projectId/roles/$roleSlug' + preLoaderRoute: typeof projectRoleDetailsBySlugPageRouteKmsImport + parentRoute: typeof kmsLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/groups/$groupId': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/groups/$groupId' + path: '/groups/$groupId' + fullPath: '/projects/secret-management/$projectId/groups/$groupId' + preLoaderRoute: typeof projectGroupDetailsByIDPageRouteSecretManagerImport parentRoute: typeof secretManagerLayoutImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/' + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/identities/$identityId': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/identities/$identityId' + path: '/identities/$identityId' + fullPath: '/projects/secret-management/$projectId/identities/$identityId' + preLoaderRoute: typeof projectIdentityDetailsByIDPageRouteSecretManagerImport + parentRoute: typeof secretManagerLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/members/$membershipId': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/members/$membershipId' + path: '/members/$membershipId' + fullPath: '/projects/secret-management/$projectId/members/$membershipId' + preLoaderRoute: typeof projectMemberDetailsByIDPageRouteSecretManagerImport + parentRoute: typeof secretManagerLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/roles/$roleSlug': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/roles/$roleSlug' + path: '/roles/$roleSlug' + fullPath: '/projects/secret-management/$projectId/roles/$roleSlug' + preLoaderRoute: typeof projectRoleDetailsBySlugPageRouteSecretManagerImport + parentRoute: typeof secretManagerLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/groups/$groupId': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/groups/$groupId' + path: '/groups/$groupId' + fullPath: '/projects/secret-scanning/$projectId/groups/$groupId' + preLoaderRoute: typeof projectGroupDetailsByIDPageRouteSecretScanningImport + parentRoute: typeof secretScanningLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/identities/$identityId': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/identities/$identityId' + path: '/identities/$identityId' + fullPath: '/projects/secret-scanning/$projectId/identities/$identityId' + preLoaderRoute: typeof projectIdentityDetailsByIDPageRouteSecretScanningImport + parentRoute: typeof secretScanningLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/members/$membershipId': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/members/$membershipId' + path: '/members/$membershipId' + fullPath: '/projects/secret-scanning/$projectId/members/$membershipId' + preLoaderRoute: typeof projectMemberDetailsByIDPageRouteSecretScanningImport + parentRoute: typeof secretScanningLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/roles/$roleSlug': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/roles/$roleSlug' + path: '/roles/$roleSlug' + fullPath: '/projects/secret-scanning/$projectId/roles/$roleSlug' + preLoaderRoute: typeof projectRoleDetailsBySlugPageRouteSecretScanningImport + parentRoute: typeof secretScanningLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/groups/$groupId': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/groups/$groupId' + path: '/groups/$groupId' + fullPath: '/projects/ssh/$projectId/groups/$groupId' + preLoaderRoute: typeof projectGroupDetailsByIDPageRouteSshImport + parentRoute: typeof sshLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/identities/$identityId': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/identities/$identityId' + path: '/identities/$identityId' + fullPath: '/projects/ssh/$projectId/identities/$identityId' + preLoaderRoute: typeof projectIdentityDetailsByIDPageRouteSshImport + parentRoute: typeof sshLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/members/$membershipId': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/members/$membershipId' + path: '/members/$membershipId' + fullPath: '/projects/ssh/$projectId/members/$membershipId' + preLoaderRoute: typeof projectMemberDetailsByIDPageRouteSshImport + parentRoute: typeof sshLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/roles/$roleSlug': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/roles/$roleSlug' + path: '/roles/$roleSlug' + fullPath: '/projects/ssh/$projectId/roles/$roleSlug' + preLoaderRoute: typeof projectRoleDetailsBySlugPageRouteSshImport + parentRoute: typeof sshLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/authorize' + path: '/aws-parameter-store/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/aws-parameter-store/authorize' + preLoaderRoute: typeof secretManagerIntegrationsAwsParameterStoreAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/create' + path: '/aws-parameter-store/create' + fullPath: '/projects/secret-management/$projectId/integrations/aws-parameter-store/create' + preLoaderRoute: typeof secretManagerIntegrationsAwsParameterStoreConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/authorize' + path: '/aws-secret-manager/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/aws-secret-manager/authorize' + preLoaderRoute: typeof secretManagerIntegrationsAwsSecretManagerAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/create' + path: '/aws-secret-manager/create' + fullPath: '/projects/secret-management/$projectId/integrations/aws-secret-manager/create' + preLoaderRoute: typeof secretManagerIntegrationsAwsSecretManagerConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/create' + path: '/azure-app-configuration/create' + fullPath: '/projects/secret-management/$projectId/integrations/azure-app-configuration/create' + preLoaderRoute: typeof secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/authorize' + path: '/azure-devops/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/azure-devops/authorize' + preLoaderRoute: typeof secretManagerIntegrationsAzureDevopsAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/create' + path: '/azure-devops/create' + fullPath: '/projects/secret-management/$projectId/integrations/azure-devops/create' + preLoaderRoute: typeof secretManagerIntegrationsAzureDevopsConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/authorize' + path: '/azure-key-vault/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/azure-key-vault/authorize' + preLoaderRoute: typeof secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/create' + path: '/azure-key-vault/create' + fullPath: '/projects/secret-management/$projectId/integrations/azure-key-vault/create' + preLoaderRoute: typeof secretManagerIntegrationsAzureKeyVaultConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/create' + path: '/bitbucket/create' + fullPath: '/projects/secret-management/$projectId/integrations/bitbucket/create' + preLoaderRoute: typeof secretManagerIntegrationsBitbucketConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/authorize' + path: '/checkly/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/checkly/authorize' + preLoaderRoute: typeof secretManagerIntegrationsChecklyAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/create' + path: '/checkly/create' + fullPath: '/projects/secret-management/$projectId/integrations/checkly/create' + preLoaderRoute: typeof secretManagerIntegrationsChecklyConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/authorize' + path: '/circleci/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/circleci/authorize' + preLoaderRoute: typeof secretManagerIntegrationsCircleCIAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/create' + path: '/circleci/create' + fullPath: '/projects/secret-management/$projectId/integrations/circleci/create' + preLoaderRoute: typeof secretManagerIntegrationsCircleCIConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/authorize' + path: '/cloud-66/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/cloud-66/authorize' + preLoaderRoute: typeof secretManagerIntegrationsCloud66AuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/create' + path: '/cloud-66/create' + fullPath: '/projects/secret-management/$projectId/integrations/cloud-66/create' + preLoaderRoute: typeof secretManagerIntegrationsCloud66ConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/authorize' + path: '/cloudflare-pages/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/cloudflare-pages/authorize' + preLoaderRoute: typeof secretManagerIntegrationsCloudflarePagesAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/create' + path: '/cloudflare-pages/create' + fullPath: '/projects/secret-management/$projectId/integrations/cloudflare-pages/create' + preLoaderRoute: typeof secretManagerIntegrationsCloudflarePagesConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/authorize' + path: '/cloudflare-workers/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/cloudflare-workers/authorize' + preLoaderRoute: typeof secretManagerIntegrationsCloudflareWorkersAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/create' + path: '/cloudflare-workers/create' + fullPath: '/projects/secret-management/$projectId/integrations/cloudflare-workers/create' + preLoaderRoute: typeof secretManagerIntegrationsCloudflareWorkersConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/authorize' + path: '/codefresh/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/codefresh/authorize' + preLoaderRoute: typeof secretManagerIntegrationsCodefreshAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/create' + path: '/codefresh/create' + fullPath: '/projects/secret-management/$projectId/integrations/codefresh/create' + preLoaderRoute: typeof secretManagerIntegrationsCodefreshConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/authorize' + path: '/databricks/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/databricks/authorize' + preLoaderRoute: typeof secretManagerIntegrationsDatabricksAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/create' + path: '/databricks/create' + fullPath: '/projects/secret-management/$projectId/integrations/databricks/create' + preLoaderRoute: typeof secretManagerIntegrationsDatabricksConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/authorize' + path: '/digital-ocean-app-platform/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/authorize' + preLoaderRoute: typeof secretManagerIntegrationsDigitalOceanAppPlatformAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/create' + path: '/digital-ocean-app-platform/create' + fullPath: '/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/create' + preLoaderRoute: typeof secretManagerIntegrationsDigitalOceanAppPlatformConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/authorize' + path: '/flyio/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/flyio/authorize' + preLoaderRoute: typeof secretManagerIntegrationsFlyioAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/create' + path: '/flyio/create' + fullPath: '/projects/secret-management/$projectId/integrations/flyio/create' + preLoaderRoute: typeof secretManagerIntegrationsFlyioConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/authorize' + path: '/gcp-secret-manager/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/gcp-secret-manager/authorize' + preLoaderRoute: typeof secretManagerIntegrationsGcpSecretManagerAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/create' + path: '/gcp-secret-manager/create' + fullPath: '/projects/secret-management/$projectId/integrations/gcp-secret-manager/create' + preLoaderRoute: typeof secretManagerIntegrationsGcpSecretManagerConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/auth-mode-selection': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/auth-mode-selection' + path: '/github/auth-mode-selection' + fullPath: '/projects/secret-management/$projectId/integrations/github/auth-mode-selection' + preLoaderRoute: typeof secretManagerIntegrationsGithubAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/create' + path: '/github/create' + fullPath: '/projects/secret-management/$projectId/integrations/github/create' + preLoaderRoute: typeof secretManagerIntegrationsGithubConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/authorize' + path: '/gitlab/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/gitlab/authorize' + preLoaderRoute: typeof secretManagerIntegrationsGitlabAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/create' + path: '/gitlab/create' + fullPath: '/projects/secret-management/$projectId/integrations/gitlab/create' + preLoaderRoute: typeof secretManagerIntegrationsGitlabConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/authorize' + path: '/hashicorp-vault/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/hashicorp-vault/authorize' + preLoaderRoute: typeof secretManagerIntegrationsHashicorpVaultAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/create' + path: '/hashicorp-vault/create' + fullPath: '/projects/secret-management/$projectId/integrations/hashicorp-vault/create' + preLoaderRoute: typeof secretManagerIntegrationsHashicorpVaultConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/authorize' + path: '/hasura-cloud/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/hasura-cloud/authorize' + preLoaderRoute: typeof secretManagerIntegrationsHasuraCloudAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/create' + path: '/hasura-cloud/create' + fullPath: '/projects/secret-management/$projectId/integrations/hasura-cloud/create' + preLoaderRoute: typeof secretManagerIntegrationsHasuraCloudConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/create' + path: '/heroku/create' + fullPath: '/projects/secret-management/$projectId/integrations/heroku/create' + preLoaderRoute: typeof secretManagerIntegrationsHerokuConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/authorize' + path: '/laravel-forge/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/laravel-forge/authorize' + preLoaderRoute: typeof secretManagerIntegrationsLaravelForgeAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/create' + path: '/laravel-forge/create' + fullPath: '/projects/secret-management/$projectId/integrations/laravel-forge/create' + preLoaderRoute: typeof secretManagerIntegrationsLaravelForgeConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/create' + path: '/netlify/create' + fullPath: '/projects/secret-management/$projectId/integrations/netlify/create' + preLoaderRoute: typeof secretManagerIntegrationsNetlifyConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/authorize' + path: '/northflank/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/northflank/authorize' + preLoaderRoute: typeof secretManagerIntegrationsNorthflankAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/create' + path: '/northflank/create' + fullPath: '/projects/secret-management/$projectId/integrations/northflank/create' + preLoaderRoute: typeof secretManagerIntegrationsNorthflankConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/authorize' + path: '/octopus-deploy/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/octopus-deploy/authorize' + preLoaderRoute: typeof secretManagerIntegrationsOctopusDeployAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/create' + path: '/octopus-deploy/create' + fullPath: '/projects/secret-management/$projectId/integrations/octopus-deploy/create' + preLoaderRoute: typeof secretManagerIntegrationsOctopusDeployConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/authorize' + path: '/qovery/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/qovery/authorize' + preLoaderRoute: typeof secretManagerIntegrationsQoveryAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/create' + path: '/qovery/create' + fullPath: '/projects/secret-management/$projectId/integrations/qovery/create' + preLoaderRoute: typeof secretManagerIntegrationsQoveryConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/authorize' + path: '/railway/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/railway/authorize' + preLoaderRoute: typeof secretManagerIntegrationsRailwayAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/create' + path: '/railway/create' + fullPath: '/projects/secret-management/$projectId/integrations/railway/create' + preLoaderRoute: typeof secretManagerIntegrationsRailwayConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/authorize' + path: '/render/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/render/authorize' + preLoaderRoute: typeof secretManagerIntegrationsRenderAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/create' + path: '/render/create' + fullPath: '/projects/secret-management/$projectId/integrations/render/create' + preLoaderRoute: typeof secretManagerIntegrationsRenderConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/authorize' + path: '/rundeck/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/rundeck/authorize' + preLoaderRoute: typeof secretManagerIntegrationsRundeckAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/create' + path: '/rundeck/create' + fullPath: '/projects/secret-management/$projectId/integrations/rundeck/create' + preLoaderRoute: typeof secretManagerIntegrationsRundeckConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/authorize' + path: '/supabase/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/supabase/authorize' + preLoaderRoute: typeof secretManagerIntegrationsSupabaseAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/create' + path: '/supabase/create' + fullPath: '/projects/secret-management/$projectId/integrations/supabase/create' + preLoaderRoute: typeof secretManagerIntegrationsSupabaseConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/authorize' + path: '/teamcity/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/teamcity/authorize' + preLoaderRoute: typeof secretManagerIntegrationsTeamcityAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/create' + path: '/teamcity/create' + fullPath: '/projects/secret-management/$projectId/integrations/teamcity/create' + preLoaderRoute: typeof secretManagerIntegrationsTeamcityConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/authorize' + path: '/terraform-cloud/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/terraform-cloud/authorize' + preLoaderRoute: typeof secretManagerIntegrationsTerraformCloudAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/create' + path: '/terraform-cloud/create' + fullPath: '/projects/secret-management/$projectId/integrations/terraform-cloud/create' + preLoaderRoute: typeof secretManagerIntegrationsTerraformCloudConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/authorize' + path: '/travisci/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/travisci/authorize' + preLoaderRoute: typeof secretManagerIntegrationsTravisCIAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/create' + path: '/travisci/create' + fullPath: '/projects/secret-management/$projectId/integrations/travisci/create' + preLoaderRoute: typeof secretManagerIntegrationsTravisCIConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/create' + path: '/vercel/create' + fullPath: '/projects/secret-management/$projectId/integrations/vercel/create' + preLoaderRoute: typeof secretManagerIntegrationsVercelConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/authorize': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/authorize' + path: '/windmill/authorize' + fullPath: '/projects/secret-management/$projectId/integrations/windmill/authorize' + preLoaderRoute: typeof secretManagerIntegrationsWindmillAuthorizePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/create': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/create' + path: '/windmill/create' + fullPath: '/projects/secret-management/$projectId/integrations/windmill/create' + preLoaderRoute: typeof secretManagerIntegrationsWindmillConfigurePageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/$type/$dataSourceId': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/$type/$dataSourceId' + path: '/$type/$dataSourceId' + fullPath: '/projects/secret-scanning/$projectId/data-sources/$type/$dataSourceId' + preLoaderRoute: typeof secretScanningSecretScanningDataSourceByIdPageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId' + path: '/commits/$environment/$folderId' + fullPath: '/projects/secret-management/$projectId/commits/$environment/$folderId' + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdImport + parentRoute: typeof secretManagerLayoutImport + } + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/' path: '/' - fullPath: '/projects/$projectId/secret-manager/commits/$environment/$folderId/' + fullPath: '/projects/secret-management/$projectId/commits/$environment/$folderId/' preLoaderRoute: typeof secretManagerCommitsPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-app-configuration/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-app-configuration/oauth2/callback' + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/oauth2/callback': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/oauth2/callback' path: '/azure-app-configuration/oauth2/callback' - fullPath: '/projects/$projectId/secret-manager/integrations/azure-app-configuration/oauth2/callback' + fullPath: '/projects/secret-management/$projectId/integrations/azure-app-configuration/oauth2/callback' preLoaderRoute: typeof secretManagerIntegrationsAzureAppConfigurationOauthCallbackPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-key-vault/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-key-vault/oauth2/callback' + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/oauth2/callback': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/oauth2/callback' path: '/azure-key-vault/oauth2/callback' - fullPath: '/projects/$projectId/secret-manager/integrations/azure-key-vault/oauth2/callback' + fullPath: '/projects/secret-management/$projectId/integrations/azure-key-vault/oauth2/callback' preLoaderRoute: typeof secretManagerIntegrationsAzureKeyVaultOauthCallbackPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/bitbucket/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/bitbucket/oauth2/callback' + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/oauth2/callback': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/oauth2/callback' path: '/bitbucket/oauth2/callback' - fullPath: '/projects/$projectId/secret-manager/integrations/bitbucket/oauth2/callback' + fullPath: '/projects/secret-management/$projectId/integrations/bitbucket/oauth2/callback' preLoaderRoute: typeof secretManagerIntegrationsBitbucketOauthCallbackPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gcp-secret-manager/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gcp-secret-manager/oauth2/callback' + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/oauth2/callback': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/oauth2/callback' path: '/gcp-secret-manager/oauth2/callback' - fullPath: '/projects/$projectId/secret-manager/integrations/gcp-secret-manager/oauth2/callback' + fullPath: '/projects/secret-management/$projectId/integrations/gcp-secret-manager/oauth2/callback' preLoaderRoute: typeof secretManagerIntegrationsGcpSecretManagerOauthCallbackPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/github/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/github/oauth2/callback' + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/oauth2/callback': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/oauth2/callback' path: '/github/oauth2/callback' - fullPath: '/projects/$projectId/secret-manager/integrations/github/oauth2/callback' + fullPath: '/projects/secret-management/$projectId/integrations/github/oauth2/callback' preLoaderRoute: typeof secretManagerIntegrationsGithubOauthCallbackPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gitlab/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gitlab/oauth2/callback' + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/oauth2/callback': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/oauth2/callback' path: '/gitlab/oauth2/callback' - fullPath: '/projects/$projectId/secret-manager/integrations/gitlab/oauth2/callback' + fullPath: '/projects/secret-management/$projectId/integrations/gitlab/oauth2/callback' preLoaderRoute: typeof secretManagerIntegrationsGitlabOauthCallbackPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/heroku/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/heroku/oauth2/callback' + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/oauth2/callback': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/oauth2/callback' path: '/heroku/oauth2/callback' - fullPath: '/projects/$projectId/secret-manager/integrations/heroku/oauth2/callback' + fullPath: '/projects/secret-management/$projectId/integrations/heroku/oauth2/callback' preLoaderRoute: typeof secretManagerIntegrationsHerokuOauthCallbackPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/netlify/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/netlify/oauth2/callback' + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/oauth2/callback': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/oauth2/callback' path: '/netlify/oauth2/callback' - fullPath: '/projects/$projectId/secret-manager/integrations/netlify/oauth2/callback' + fullPath: '/projects/secret-management/$projectId/integrations/netlify/oauth2/callback' preLoaderRoute: typeof secretManagerIntegrationsNetlifyOauthCallbackPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/secret-syncs/$destination/$syncId': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/secret-syncs/$destination/$syncId' + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/secret-syncs/$destination/$syncId': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/secret-syncs/$destination/$syncId' path: '/secret-syncs/$destination/$syncId' - fullPath: '/projects/$projectId/secret-manager/integrations/secret-syncs/$destination/$syncId' + fullPath: '/projects/secret-management/$projectId/integrations/secret-syncs/$destination/$syncId' preLoaderRoute: typeof secretManagerSecretSyncDetailsByIDPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/vercel/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/vercel/oauth2/callback' + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/oauth2/callback': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/oauth2/callback' path: '/vercel/oauth2/callback' - fullPath: '/projects/$projectId/secret-manager/integrations/vercel/oauth2/callback' + fullPath: '/projects/secret-management/$projectId/integrations/vercel/oauth2/callback' preLoaderRoute: typeof secretManagerIntegrationsVercelOauthCallbackPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/$commitId': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/$commitId' + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId' path: '/$commitId' - fullPath: '/projects/$projectId/secret-manager/commits/$environment/$folderId/$commitId' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdImport + fullPath: '/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId' + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/$commitId/': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/$commitId/' + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/' path: '/' - fullPath: '/projects/$projectId/secret-manager/commits/$environment/$folderId/$commitId/' + fullPath: '/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId/' preLoaderRoute: typeof secretManagerCommitDetailsPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdImport } - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/$commitId/restore': { - id: '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/$commitId/restore' + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/restore': { + id: '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/restore' path: '/restore' - fullPath: '/projects/$projectId/secret-manager/commits/$environment/$folderId/$commitId/restore' + fullPath: '/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId/restore' preLoaderRoute: typeof secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdImport } } } // Create and export the route tree +interface AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRouteChildren { + secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectRoute: typeof secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectRoute + secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectRoute: typeof secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectRoute + secretManagerIntegrationsRouteBitbucketOauthRedirectRoute: typeof secretManagerIntegrationsRouteBitbucketOauthRedirectRoute + secretManagerIntegrationsRouteGcpOauthRedirectRoute: typeof secretManagerIntegrationsRouteGcpOauthRedirectRoute + secretManagerIntegrationsRouteGithubOauthRedirectRoute: typeof secretManagerIntegrationsRouteGithubOauthRedirectRoute + secretManagerIntegrationsRouteGitlabOauthRedirectRoute: typeof secretManagerIntegrationsRouteGitlabOauthRedirectRoute + secretManagerIntegrationsRouteHerokuOauthRedirectRoute: typeof secretManagerIntegrationsRouteHerokuOauthRedirectRoute + secretManagerIntegrationsRouteNetlifyOauthRedirectRoute: typeof secretManagerIntegrationsRouteNetlifyOauthRedirectRoute + secretManagerIntegrationsRouteVercelOauthRedirectRoute: typeof secretManagerIntegrationsRouteVercelOauthRedirectRoute +} + +const AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRouteChildren = + { + secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectRoute: + secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectRoute, + secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectRoute: + secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectRoute, + secretManagerIntegrationsRouteBitbucketOauthRedirectRoute: + secretManagerIntegrationsRouteBitbucketOauthRedirectRoute, + secretManagerIntegrationsRouteGcpOauthRedirectRoute: + secretManagerIntegrationsRouteGcpOauthRedirectRoute, + secretManagerIntegrationsRouteGithubOauthRedirectRoute: + secretManagerIntegrationsRouteGithubOauthRedirectRoute, + secretManagerIntegrationsRouteGitlabOauthRedirectRoute: + secretManagerIntegrationsRouteGitlabOauthRedirectRoute, + secretManagerIntegrationsRouteHerokuOauthRedirectRoute: + secretManagerIntegrationsRouteHerokuOauthRedirectRoute, + secretManagerIntegrationsRouteNetlifyOauthRedirectRoute: + secretManagerIntegrationsRouteNetlifyOauthRedirectRoute, + secretManagerIntegrationsRouteVercelOauthRedirectRoute: + secretManagerIntegrationsRouteVercelOauthRedirectRoute, + } + +const AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRouteWithChildren = + AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute._addFileChildren( + AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRouteChildren, + ) + interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRouteChildren { organizationAppConnectionsAppConnectionsPageRouteRoute: typeof organizationAppConnectionsAppConnectionsPageRouteRoute organizationAppConnectionsOauthCallbackPageRouteRoute: typeof organizationAppConnectionsOauthCallbackPageRouteRoute @@ -3454,51 +3727,42 @@ const AuthenticateInjectOrgDetailsOrgLayoutOrganizationRouteWithChildren = AuthenticateInjectOrgDetailsOrgLayoutOrganizationRouteChildren, ) -interface projectLayoutGeneralRouteChildren { - projectAccessControlPageRouteRoute: typeof projectAccessControlPageRouteRoute - projectSettingsPageRouteRoute: typeof projectSettingsPageRouteRoute - projectGroupDetailsByIDPageRouteRoute: typeof projectGroupDetailsByIDPageRouteRoute - projectIdentityDetailsByIDPageRouteRoute: typeof projectIdentityDetailsByIDPageRouteRoute - projectMemberDetailsByIDPageRouteRoute: typeof projectMemberDetailsByIDPageRouteRoute - projectRoleDetailsBySlugPageRouteRoute: typeof projectRoleDetailsBySlugPageRouteRoute +interface AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRouteChildren { + secretManagerRedirectsRedirectApprovalPageRoute: typeof secretManagerRedirectsRedirectApprovalPageRoute } -const projectLayoutGeneralRouteChildren: projectLayoutGeneralRouteChildren = { - projectAccessControlPageRouteRoute: projectAccessControlPageRouteRoute, - projectSettingsPageRouteRoute: projectSettingsPageRouteRoute, - projectGroupDetailsByIDPageRouteRoute: projectGroupDetailsByIDPageRouteRoute, - projectIdentityDetailsByIDPageRouteRoute: - projectIdentityDetailsByIDPageRouteRoute, - projectMemberDetailsByIDPageRouteRoute: - projectMemberDetailsByIDPageRouteRoute, - projectRoleDetailsBySlugPageRouteRoute: - projectRoleDetailsBySlugPageRouteRoute, -} +const AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRouteChildren = + { + secretManagerRedirectsRedirectApprovalPageRoute: + secretManagerRedirectsRedirectApprovalPageRoute, + } -const projectLayoutGeneralRouteWithChildren = - projectLayoutGeneralRoute._addFileChildren(projectLayoutGeneralRouteChildren) +const AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRouteWithChildren = + AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRoute._addFileChildren( + AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRouteChildren, + ) -interface AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutCertificateTemplatesRouteChildren { +interface AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesRouteChildren { certManagerPkiTemplateListPageRouteRoute: typeof certManagerPkiTemplateListPageRouteRoute } -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutCertificateTemplatesRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutCertificateTemplatesRouteChildren = +const AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesRouteChildren = { certManagerPkiTemplateListPageRouteRoute: certManagerPkiTemplateListPageRouteRoute, } -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutCertificateTemplatesRouteWithChildren = - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutCertificateTemplatesRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutCertificateTemplatesRouteChildren, +const AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesRouteWithChildren = + AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesRoute._addFileChildren( + AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesRouteChildren, ) -interface AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutSubscribersRouteChildren { +interface AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutSubscribersRouteChildren { certManagerPkiSubscribersPageRouteRoute: typeof certManagerPkiSubscribersPageRouteRoute certManagerPkiSubscriberDetailsByIDPageRouteRoute: typeof certManagerPkiSubscriberDetailsByIDPageRouteRoute } -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutSubscribersRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutSubscribersRouteChildren = +const AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutSubscribersRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutSubscribersRouteChildren = { certManagerPkiSubscribersPageRouteRoute: certManagerPkiSubscribersPageRouteRoute, @@ -3506,9 +3770,9 @@ const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertMan certManagerPkiSubscriberDetailsByIDPageRouteRoute, } -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutSubscribersRouteWithChildren = - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutSubscribersRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutSubscribersRouteChildren, +const AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutSubscribersRouteWithChildren = + AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutSubscribersRoute._addFileChildren( + AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutSubscribersRouteChildren, ) interface certManagerLayoutRouteChildren { @@ -3516,10 +3780,15 @@ interface certManagerLayoutRouteChildren { certManagerCertificateAuthoritiesPageRouteRoute: typeof certManagerCertificateAuthoritiesPageRouteRoute certManagerCertificatesPageRouteRoute: typeof certManagerCertificatesPageRouteRoute certManagerSettingsPageRouteRoute: typeof certManagerSettingsPageRouteRoute - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutCertificateTemplatesRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutCertificateTemplatesRouteWithChildren - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutSubscribersRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutSubscribersRouteWithChildren + projectAccessControlPageRouteCertManagerRoute: typeof projectAccessControlPageRouteCertManagerRoute + AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesRouteWithChildren + AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutSubscribersRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutSubscribersRouteWithChildren certManagerCertAuthDetailsByIDPageRouteRoute: typeof certManagerCertAuthDetailsByIDPageRouteRoute + projectGroupDetailsByIDPageRouteCertManagerRoute: typeof projectGroupDetailsByIDPageRouteCertManagerRoute + projectIdentityDetailsByIDPageRouteCertManagerRoute: typeof projectIdentityDetailsByIDPageRouteCertManagerRoute + projectMemberDetailsByIDPageRouteCertManagerRoute: typeof projectMemberDetailsByIDPageRouteCertManagerRoute certManagerPkiCollectionDetailsByIDPageRoutesRoute: typeof certManagerPkiCollectionDetailsByIDPageRoutesRoute + projectRoleDetailsBySlugPageRouteCertManagerRoute: typeof projectRoleDetailsBySlugPageRouteCertManagerRoute } const certManagerLayoutRouteChildren: certManagerLayoutRouteChildren = { @@ -3528,103 +3797,88 @@ const certManagerLayoutRouteChildren: certManagerLayoutRouteChildren = { certManagerCertificateAuthoritiesPageRouteRoute, certManagerCertificatesPageRouteRoute: certManagerCertificatesPageRouteRoute, certManagerSettingsPageRouteRoute: certManagerSettingsPageRouteRoute, - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutCertificateTemplatesRoute: - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutCertificateTemplatesRouteWithChildren, - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutSubscribersRoute: - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutSubscribersRouteWithChildren, + projectAccessControlPageRouteCertManagerRoute: + projectAccessControlPageRouteCertManagerRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesRoute: + AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesRouteWithChildren, + AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutSubscribersRoute: + AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutSubscribersRouteWithChildren, certManagerCertAuthDetailsByIDPageRouteRoute: certManagerCertAuthDetailsByIDPageRouteRoute, + projectGroupDetailsByIDPageRouteCertManagerRoute: + projectGroupDetailsByIDPageRouteCertManagerRoute, + projectIdentityDetailsByIDPageRouteCertManagerRoute: + projectIdentityDetailsByIDPageRouteCertManagerRoute, + projectMemberDetailsByIDPageRouteCertManagerRoute: + projectMemberDetailsByIDPageRouteCertManagerRoute, certManagerPkiCollectionDetailsByIDPageRoutesRoute: certManagerPkiCollectionDetailsByIDPageRoutesRoute, + projectRoleDetailsBySlugPageRouteCertManagerRoute: + projectRoleDetailsBySlugPageRouteCertManagerRoute, } const certManagerLayoutRouteWithChildren = certManagerLayoutRoute._addFileChildren(certManagerLayoutRouteChildren) -interface AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerRouteChildren { +interface AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdRouteChildren { certManagerLayoutRoute: typeof certManagerLayoutRouteWithChildren } -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerRouteChildren = +const AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdRouteChildren = { certManagerLayoutRoute: certManagerLayoutRouteWithChildren, } -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerRouteWithChildren = - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerRouteChildren, - ) - -interface AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsRouteChildren { - secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectRoute: typeof secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectRoute - secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectRoute: typeof secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectRoute - secretManagerIntegrationsRouteBitbucketOauthRedirectRoute: typeof secretManagerIntegrationsRouteBitbucketOauthRedirectRoute - secretManagerIntegrationsRouteGcpOauthRedirectRoute: typeof secretManagerIntegrationsRouteGcpOauthRedirectRoute - secretManagerIntegrationsRouteGithubOauthRedirectRoute: typeof secretManagerIntegrationsRouteGithubOauthRedirectRoute - secretManagerIntegrationsRouteGitlabOauthRedirectRoute: typeof secretManagerIntegrationsRouteGitlabOauthRedirectRoute - secretManagerIntegrationsRouteHerokuOauthRedirectRoute: typeof secretManagerIntegrationsRouteHerokuOauthRedirectRoute - secretManagerIntegrationsRouteNetlifyOauthRedirectRoute: typeof secretManagerIntegrationsRouteNetlifyOauthRedirectRoute - secretManagerIntegrationsRouteVercelOauthRedirectRoute: typeof secretManagerIntegrationsRouteVercelOauthRedirectRoute -} - -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsRouteChildren = - { - secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectRoute: - secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectRoute, - secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectRoute: - secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectRoute, - secretManagerIntegrationsRouteBitbucketOauthRedirectRoute: - secretManagerIntegrationsRouteBitbucketOauthRedirectRoute, - secretManagerIntegrationsRouteGcpOauthRedirectRoute: - secretManagerIntegrationsRouteGcpOauthRedirectRoute, - secretManagerIntegrationsRouteGithubOauthRedirectRoute: - secretManagerIntegrationsRouteGithubOauthRedirectRoute, - secretManagerIntegrationsRouteGitlabOauthRedirectRoute: - secretManagerIntegrationsRouteGitlabOauthRedirectRoute, - secretManagerIntegrationsRouteHerokuOauthRedirectRoute: - secretManagerIntegrationsRouteHerokuOauthRedirectRoute, - secretManagerIntegrationsRouteNetlifyOauthRedirectRoute: - secretManagerIntegrationsRouteNetlifyOauthRedirectRoute, - secretManagerIntegrationsRouteVercelOauthRedirectRoute: - secretManagerIntegrationsRouteVercelOauthRedirectRoute, - } - -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsRouteWithChildren = - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsRouteChildren, +const AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdRouteWithChildren = + AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdRoute._addFileChildren( + AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdRouteChildren, ) interface kmsLayoutRouteChildren { kmsKmipPageRouteRoute: typeof kmsKmipPageRouteRoute kmsOverviewPageRouteRoute: typeof kmsOverviewPageRouteRoute kmsSettingsPageRouteRoute: typeof kmsSettingsPageRouteRoute + projectAccessControlPageRouteKmsRoute: typeof projectAccessControlPageRouteKmsRoute + projectGroupDetailsByIDPageRouteKmsRoute: typeof projectGroupDetailsByIDPageRouteKmsRoute + projectIdentityDetailsByIDPageRouteKmsRoute: typeof projectIdentityDetailsByIDPageRouteKmsRoute + projectMemberDetailsByIDPageRouteKmsRoute: typeof projectMemberDetailsByIDPageRouteKmsRoute + projectRoleDetailsBySlugPageRouteKmsRoute: typeof projectRoleDetailsBySlugPageRouteKmsRoute } const kmsLayoutRouteChildren: kmsLayoutRouteChildren = { kmsKmipPageRouteRoute: kmsKmipPageRouteRoute, kmsOverviewPageRouteRoute: kmsOverviewPageRouteRoute, kmsSettingsPageRouteRoute: kmsSettingsPageRouteRoute, + projectAccessControlPageRouteKmsRoute: projectAccessControlPageRouteKmsRoute, + projectGroupDetailsByIDPageRouteKmsRoute: + projectGroupDetailsByIDPageRouteKmsRoute, + projectIdentityDetailsByIDPageRouteKmsRoute: + projectIdentityDetailsByIDPageRouteKmsRoute, + projectMemberDetailsByIDPageRouteKmsRoute: + projectMemberDetailsByIDPageRouteKmsRoute, + projectRoleDetailsBySlugPageRouteKmsRoute: + projectRoleDetailsBySlugPageRouteKmsRoute, } const kmsLayoutRouteWithChildren = kmsLayoutRoute._addFileChildren( kmsLayoutRouteChildren, ) -interface AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutKmsRouteChildren { +interface AuthenticateInjectOrgDetailsOrgLayoutProjectsKmsProjectIdRouteChildren { kmsLayoutRoute: typeof kmsLayoutRouteWithChildren } -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutKmsRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutKmsRouteChildren = +const AuthenticateInjectOrgDetailsOrgLayoutProjectsKmsProjectIdRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutProjectsKmsProjectIdRouteChildren = { kmsLayoutRoute: kmsLayoutRouteWithChildren, } -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutKmsRouteWithChildren = - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutKmsRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutKmsRouteChildren, +const AuthenticateInjectOrgDetailsOrgLayoutProjectsKmsProjectIdRouteWithChildren = + AuthenticateInjectOrgDetailsOrgLayoutProjectsKmsProjectIdRoute._addFileChildren( + AuthenticateInjectOrgDetailsOrgLayoutProjectsKmsProjectIdRouteChildren, ) -interface AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRouteChildren { +interface AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRouteChildren { secretManagerIntegrationsListPageRouteRoute: typeof secretManagerIntegrationsListPageRouteRoute secretManagerIntegrationsDetailsByIDPageRouteRoute: typeof secretManagerIntegrationsDetailsByIDPageRouteRoute secretManagerIntegrationsSelectIntegrationAuthPageRouteRoute: typeof secretManagerIntegrationsSelectIntegrationAuthPageRouteRoute @@ -3705,7 +3959,7 @@ interface AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSec secretManagerIntegrationsVercelOauthCallbackPageRouteRoute: typeof secretManagerIntegrationsVercelOauthCallbackPageRouteRoute } -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRouteChildren = +const AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRouteChildren = { secretManagerIntegrationsListPageRouteRoute: secretManagerIntegrationsListPageRouteRoute, @@ -3865,17 +4119,17 @@ const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretM secretManagerIntegrationsVercelOauthCallbackPageRouteRoute, } -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRouteWithChildren = - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRouteChildren, +const AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRouteWithChildren = + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute._addFileChildren( + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRouteChildren, ) -interface AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteChildren { +interface AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteChildren { secretManagerCommitDetailsPageRouteRoute: typeof secretManagerCommitDetailsPageRouteRoute secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteRoute: typeof secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteRoute } -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteChildren = +const AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteChildren = { secretManagerCommitDetailsPageRouteRoute: secretManagerCommitDetailsPageRouteRoute, @@ -3883,26 +4137,26 @@ const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretM secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteRoute, } -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteWithChildren = - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteChildren, +const AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteWithChildren = + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRoute._addFileChildren( + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteChildren, ) -interface AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdRouteChildren { +interface AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRouteChildren { secretManagerCommitsPageRouteRoute: typeof secretManagerCommitsPageRouteRoute - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteWithChildren + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteWithChildren } -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdRouteChildren = +const AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRouteChildren = { secretManagerCommitsPageRouteRoute: secretManagerCommitsPageRouteRoute, - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRoute: - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteWithChildren, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRoute: + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteWithChildren, } -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdRouteWithChildren = - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdRouteChildren, +const AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRouteWithChildren = + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRoute._addFileChildren( + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRouteChildren, ) interface secretManagerLayoutRouteChildren { @@ -3911,9 +4165,14 @@ interface secretManagerLayoutRouteChildren { secretManagerOverviewPageRouteRoute: typeof secretManagerOverviewPageRouteRoute secretManagerSecretRotationPageRouteRoute: typeof secretManagerSecretRotationPageRouteRoute secretManagerSettingsPageRouteRoute: typeof secretManagerSettingsPageRouteRoute - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRouteWithChildren + projectAccessControlPageRouteSecretManagerRoute: typeof projectAccessControlPageRouteSecretManagerRoute + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRouteWithChildren secretManagerSecretDashboardPageRouteRoute: typeof secretManagerSecretDashboardPageRouteRoute - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdRouteWithChildren + projectGroupDetailsByIDPageRouteSecretManagerRoute: typeof projectGroupDetailsByIDPageRouteSecretManagerRoute + projectIdentityDetailsByIDPageRouteSecretManagerRoute: typeof projectIdentityDetailsByIDPageRouteSecretManagerRoute + projectMemberDetailsByIDPageRouteSecretManagerRoute: typeof projectMemberDetailsByIDPageRouteSecretManagerRoute + projectRoleDetailsBySlugPageRouteSecretManagerRoute: typeof projectRoleDetailsBySlugPageRouteSecretManagerRoute + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRouteWithChildren } const secretManagerLayoutRouteChildren: secretManagerLayoutRouteChildren = { @@ -3925,37 +4184,47 @@ const secretManagerLayoutRouteChildren: secretManagerLayoutRouteChildren = { secretManagerSecretRotationPageRouteRoute: secretManagerSecretRotationPageRouteRoute, secretManagerSettingsPageRouteRoute: secretManagerSettingsPageRouteRoute, - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRoute: - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRouteWithChildren, + projectAccessControlPageRouteSecretManagerRoute: + projectAccessControlPageRouteSecretManagerRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute: + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRouteWithChildren, secretManagerSecretDashboardPageRouteRoute: secretManagerSecretDashboardPageRouteRoute, - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdRoute: - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdRouteWithChildren, + projectGroupDetailsByIDPageRouteSecretManagerRoute: + projectGroupDetailsByIDPageRouteSecretManagerRoute, + projectIdentityDetailsByIDPageRouteSecretManagerRoute: + projectIdentityDetailsByIDPageRouteSecretManagerRoute, + projectMemberDetailsByIDPageRouteSecretManagerRoute: + projectMemberDetailsByIDPageRouteSecretManagerRoute, + projectRoleDetailsBySlugPageRouteSecretManagerRoute: + projectRoleDetailsBySlugPageRouteSecretManagerRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRoute: + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRouteWithChildren, } const secretManagerLayoutRouteWithChildren = secretManagerLayoutRoute._addFileChildren(secretManagerLayoutRouteChildren) -interface AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerRouteChildren { +interface AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdRouteChildren { secretManagerLayoutRoute: typeof secretManagerLayoutRouteWithChildren } -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerRouteChildren = +const AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdRouteChildren = { secretManagerLayoutRoute: secretManagerLayoutRouteWithChildren, } -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerRouteWithChildren = - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerRouteChildren, +const AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdRouteWithChildren = + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdRoute._addFileChildren( + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdRouteChildren, ) -interface AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningSecretScanningLayoutDataSourcesRouteChildren { +interface AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRouteChildren { secretScanningSecretScanningDataSourcesPageRouteRoute: typeof secretScanningSecretScanningDataSourcesPageRouteRoute secretScanningSecretScanningDataSourceByIdPageRouteRoute: typeof secretScanningSecretScanningDataSourceByIdPageRouteRoute } -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningSecretScanningLayoutDataSourcesRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningSecretScanningLayoutDataSourcesRouteChildren = +const AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRouteChildren = { secretScanningSecretScanningDataSourcesPageRouteRoute: secretScanningSecretScanningDataSourcesPageRouteRoute, @@ -3963,40 +4232,55 @@ const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretS secretScanningSecretScanningDataSourceByIdPageRouteRoute, } -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningSecretScanningLayoutDataSourcesRouteWithChildren = - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningSecretScanningLayoutDataSourcesRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningSecretScanningLayoutDataSourcesRouteChildren, +const AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRouteWithChildren = + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRoute._addFileChildren( + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRouteChildren, ) interface secretScanningLayoutRouteChildren { secretScanningSecretScanningFindingsPageRouteRoute: typeof secretScanningSecretScanningFindingsPageRouteRoute secretScanningSettingsPageRouteRoute: typeof secretScanningSettingsPageRouteRoute - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningSecretScanningLayoutDataSourcesRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningSecretScanningLayoutDataSourcesRouteWithChildren + projectAccessControlPageRouteSecretScanningRoute: typeof projectAccessControlPageRouteSecretScanningRoute + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRouteWithChildren + projectGroupDetailsByIDPageRouteSecretScanningRoute: typeof projectGroupDetailsByIDPageRouteSecretScanningRoute + projectIdentityDetailsByIDPageRouteSecretScanningRoute: typeof projectIdentityDetailsByIDPageRouteSecretScanningRoute + projectMemberDetailsByIDPageRouteSecretScanningRoute: typeof projectMemberDetailsByIDPageRouteSecretScanningRoute + projectRoleDetailsBySlugPageRouteSecretScanningRoute: typeof projectRoleDetailsBySlugPageRouteSecretScanningRoute } const secretScanningLayoutRouteChildren: secretScanningLayoutRouteChildren = { secretScanningSecretScanningFindingsPageRouteRoute: secretScanningSecretScanningFindingsPageRouteRoute, secretScanningSettingsPageRouteRoute: secretScanningSettingsPageRouteRoute, - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningSecretScanningLayoutDataSourcesRoute: - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningSecretScanningLayoutDataSourcesRouteWithChildren, + projectAccessControlPageRouteSecretScanningRoute: + projectAccessControlPageRouteSecretScanningRoute, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRoute: + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRouteWithChildren, + projectGroupDetailsByIDPageRouteSecretScanningRoute: + projectGroupDetailsByIDPageRouteSecretScanningRoute, + projectIdentityDetailsByIDPageRouteSecretScanningRoute: + projectIdentityDetailsByIDPageRouteSecretScanningRoute, + projectMemberDetailsByIDPageRouteSecretScanningRoute: + projectMemberDetailsByIDPageRouteSecretScanningRoute, + projectRoleDetailsBySlugPageRouteSecretScanningRoute: + projectRoleDetailsBySlugPageRouteSecretScanningRoute, } const secretScanningLayoutRouteWithChildren = secretScanningLayoutRoute._addFileChildren(secretScanningLayoutRouteChildren) -interface AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningRouteChildren { +interface AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdRouteChildren { secretScanningLayoutRoute: typeof secretScanningLayoutRouteWithChildren } -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningRouteChildren = +const AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdRouteChildren = { secretScanningLayoutRoute: secretScanningLayoutRouteWithChildren, } -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningRouteWithChildren = - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningRouteChildren, +const AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdRouteWithChildren = + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdRoute._addFileChildren( + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdRouteChildren, ) interface sshLayoutRouteChildren { @@ -4004,8 +4288,13 @@ interface sshLayoutRouteChildren { sshSshCertsPageRouteRoute: typeof sshSshCertsPageRouteRoute sshSshHostsPageRouteRoute: typeof sshSshHostsPageRouteRoute sshSettingsPageRouteRoute: typeof sshSettingsPageRouteRoute + projectAccessControlPageRouteSshRoute: typeof projectAccessControlPageRouteSshRoute sshSshCaByIDPageRouteRoute: typeof sshSshCaByIDPageRouteRoute sshSshHostGroupDetailsByIDPageRouteRoute: typeof sshSshHostGroupDetailsByIDPageRouteRoute + projectGroupDetailsByIDPageRouteSshRoute: typeof projectGroupDetailsByIDPageRouteSshRoute + projectIdentityDetailsByIDPageRouteSshRoute: typeof projectIdentityDetailsByIDPageRouteSshRoute + projectMemberDetailsByIDPageRouteSshRoute: typeof projectMemberDetailsByIDPageRouteSshRoute + projectRoleDetailsBySlugPageRouteSshRoute: typeof projectRoleDetailsBySlugPageRouteSshRoute } const sshLayoutRouteChildren: sshLayoutRouteChildren = { @@ -4013,101 +4302,66 @@ const sshLayoutRouteChildren: sshLayoutRouteChildren = { sshSshCertsPageRouteRoute: sshSshCertsPageRouteRoute, sshSshHostsPageRouteRoute: sshSshHostsPageRouteRoute, sshSettingsPageRouteRoute: sshSettingsPageRouteRoute, + projectAccessControlPageRouteSshRoute: projectAccessControlPageRouteSshRoute, sshSshCaByIDPageRouteRoute: sshSshCaByIDPageRouteRoute, sshSshHostGroupDetailsByIDPageRouteRoute: sshSshHostGroupDetailsByIDPageRouteRoute, + projectGroupDetailsByIDPageRouteSshRoute: + projectGroupDetailsByIDPageRouteSshRoute, + projectIdentityDetailsByIDPageRouteSshRoute: + projectIdentityDetailsByIDPageRouteSshRoute, + projectMemberDetailsByIDPageRouteSshRoute: + projectMemberDetailsByIDPageRouteSshRoute, + projectRoleDetailsBySlugPageRouteSshRoute: + projectRoleDetailsBySlugPageRouteSshRoute, } const sshLayoutRouteWithChildren = sshLayoutRoute._addFileChildren( sshLayoutRouteChildren, ) -interface AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSshRouteChildren { +interface AuthenticateInjectOrgDetailsOrgLayoutProjectsSshProjectIdRouteChildren { sshLayoutRoute: typeof sshLayoutRouteWithChildren } -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSshRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSshRouteChildren = +const AuthenticateInjectOrgDetailsOrgLayoutProjectsSshProjectIdRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutProjectsSshProjectIdRouteChildren = { sshLayoutRoute: sshLayoutRouteWithChildren, } -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSshRouteWithChildren = - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSshRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSshRouteChildren, - ) - -interface projectLayoutRouteChildren { - projectLayoutGeneralRoute: typeof projectLayoutGeneralRouteWithChildren - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerRouteWithChildren - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsRouteWithChildren - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutKmsRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutKmsRouteWithChildren - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerRouteWithChildren - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningRouteWithChildren - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSshRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSshRouteWithChildren -} - -const projectLayoutRouteChildren: projectLayoutRouteChildren = { - projectLayoutGeneralRoute: projectLayoutGeneralRouteWithChildren, - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerRoute: - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerRouteWithChildren, - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsRoute: - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsRouteWithChildren, - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutKmsRoute: - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutKmsRouteWithChildren, - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerRoute: - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerRouteWithChildren, - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningRoute: - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningRouteWithChildren, - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSshRoute: - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSshRouteWithChildren, -} - -const projectLayoutRouteWithChildren = projectLayoutRoute._addFileChildren( - projectLayoutRouteChildren, -) - -interface AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdRouteChildren { - projectLayoutRoute: typeof projectLayoutRouteWithChildren -} - -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdRouteChildren = - { - projectLayoutRoute: projectLayoutRouteWithChildren, - } - -const AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdRouteWithChildren = - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdRouteChildren, - ) - -interface AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRouteChildren { - secretManagerRedirectsRedirectApprovalPageRoute: typeof secretManagerRedirectsRedirectApprovalPageRoute -} - -const AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRouteChildren = - { - secretManagerRedirectsRedirectApprovalPageRoute: - secretManagerRedirectsRedirectApprovalPageRoute, - } - -const AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRouteWithChildren = - AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRouteChildren, +const AuthenticateInjectOrgDetailsOrgLayoutProjectsSshProjectIdRouteWithChildren = + AuthenticateInjectOrgDetailsOrgLayoutProjectsSshProjectIdRoute._addFileChildren( + AuthenticateInjectOrgDetailsOrgLayoutProjectsSshProjectIdRouteChildren, ) interface organizationLayoutRouteChildren { + AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRouteWithChildren AuthenticateInjectOrgDetailsOrgLayoutOrganizationRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationRouteWithChildren - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdRouteWithChildren AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRouteWithChildren + AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdRouteWithChildren + AuthenticateInjectOrgDetailsOrgLayoutProjectsKmsProjectIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsKmsProjectIdRouteWithChildren + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdRouteWithChildren + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdRouteWithChildren + AuthenticateInjectOrgDetailsOrgLayoutProjectsSshProjectIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSshProjectIdRouteWithChildren } const organizationLayoutRouteChildren: organizationLayoutRouteChildren = { + AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute: + AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRouteWithChildren, AuthenticateInjectOrgDetailsOrgLayoutOrganizationRoute: AuthenticateInjectOrgDetailsOrgLayoutOrganizationRouteWithChildren, - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdRoute: - AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdRouteWithChildren, AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRoute: AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRouteWithChildren, + AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdRoute: + AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdRouteWithChildren, + AuthenticateInjectOrgDetailsOrgLayoutProjectsKmsProjectIdRoute: + AuthenticateInjectOrgDetailsOrgLayoutProjectsKmsProjectIdRouteWithChildren, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdRoute: + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdRouteWithChildren, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdRoute: + AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdRouteWithChildren, + AuthenticateInjectOrgDetailsOrgLayoutProjectsSshProjectIdRoute: + AuthenticateInjectOrgDetailsOrgLayoutProjectsSshProjectIdRouteWithChildren, } const organizationLayoutRouteWithChildren = @@ -4322,6 +4576,7 @@ export interface FileRoutesByFullPath { '/personal-settings/': typeof userPersonalSettingsPageRouteRoute '/login/provider/error': typeof authProviderErrorPageRouteRoute '/login/provider/success': typeof authProviderSuccessPageRouteRoute + '/integrations': typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRouteWithChildren '/organization': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationRouteWithChildren '/admin/': typeof adminGeneralPageRouteRoute '/organization/access-management': typeof organizationAccessManagementPageRouteRoute @@ -4338,7 +4593,6 @@ export interface FileRoutesByFullPath { '/organization/gateways': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRouteWithChildren '/organization/secret-sharing': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteWithChildren '/organization/settings': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRouteWithChildren - '/projects/$projectId': typeof projectLayoutGeneralRouteWithChildren '/secret-manager/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRouteWithChildren '/organization/app-connections/': typeof organizationAppConnectionsAppConnectionsPageRouteRoute '/organization/gateways/': typeof organizationGatewaysGatewayListPageRouteRoute @@ -4352,145 +4606,163 @@ export interface FileRoutesByFullPath { '/admin/resources/machine-identities': typeof adminMachineIdentitiesResourcesPageRouteRoute '/admin/resources/organizations': typeof adminOrganizationResourcesPageRouteRoute '/admin/resources/user-identities': typeof adminUserIdentitiesResourcesPageRouteRoute + '/projects/cert-management/$projectId': typeof certManagerLayoutRouteWithChildren + '/projects/kms/$projectId': typeof kmsLayoutRouteWithChildren + '/projects/secret-management/$projectId': typeof secretManagerLayoutRouteWithChildren + '/projects/secret-scanning/$projectId': typeof secretScanningLayoutRouteWithChildren + '/projects/ssh/$projectId': typeof sshLayoutRouteWithChildren '/secret-manager/$projectId/approval': typeof secretManagerRedirectsRedirectApprovalPageRoute '/organization/settings/oauth/callback': typeof organizationSettingsPageOauthCallbackPageRouteRoute - '/projects/$projectId/cert-manager': typeof certManagerLayoutRouteWithChildren - '/projects/$projectId/integrations': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsRouteWithChildren - '/projects/$projectId/kms': typeof kmsLayoutRouteWithChildren - '/projects/$projectId/secret-manager': typeof secretManagerLayoutRouteWithChildren - '/projects/$projectId/secret-scanning': typeof secretScanningLayoutRouteWithChildren - '/projects/$projectId/ssh': typeof sshLayoutRouteWithChildren + '/integrations/azure-app-configuration/oauth2/callback': typeof secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectRoute + '/integrations/azure-key-vault/oauth2/callback': typeof secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectRoute + '/integrations/bitbucket/oauth2/callback': typeof secretManagerIntegrationsRouteBitbucketOauthRedirectRoute + '/integrations/gcp-secret-manager/oauth2/callback': typeof secretManagerIntegrationsRouteGcpOauthRedirectRoute + '/integrations/github/oauth2/callback': typeof secretManagerIntegrationsRouteGithubOauthRedirectRoute + '/integrations/gitlab/oauth2/callback': typeof secretManagerIntegrationsRouteGitlabOauthRedirectRoute + '/integrations/heroku/oauth2/callback': typeof secretManagerIntegrationsRouteHerokuOauthRedirectRoute + '/integrations/netlify/oauth2/callback': typeof secretManagerIntegrationsRouteNetlifyOauthRedirectRoute + '/integrations/vercel/oauth2/callback': typeof secretManagerIntegrationsRouteVercelOauthRedirectRoute '/organization/app-connections/$appConnection/oauth/callback': typeof organizationAppConnectionsOauthCallbackPageRouteRoute - '/projects/$projectId/access-management': typeof projectAccessControlPageRouteRoute - '/projects/$projectId/settings': typeof projectSettingsPageRouteRoute - '/projects/$projectId/groups/$groupId': typeof projectGroupDetailsByIDPageRouteRoute - '/projects/$projectId/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteRoute - '/projects/$projectId/members/$membershipId': typeof projectMemberDetailsByIDPageRouteRoute - '/projects/$projectId/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteRoute - '/projects/$projectId/cert-manager/alerting': typeof certManagerAlertingPageRouteRoute - '/projects/$projectId/cert-manager/certificate-authorities': typeof certManagerCertificateAuthoritiesPageRouteRoute - '/projects/$projectId/cert-manager/certificates': typeof certManagerCertificatesPageRouteRoute - '/projects/$projectId/cert-manager/settings': typeof certManagerSettingsPageRouteRoute - '/projects/$projectId/kms/kmip': typeof kmsKmipPageRouteRoute - '/projects/$projectId/kms/overview': typeof kmsOverviewPageRouteRoute - '/projects/$projectId/kms/settings': typeof kmsSettingsPageRouteRoute - '/projects/$projectId/secret-manager/allowlist': typeof secretManagerIPAllowlistPageRouteRoute - '/projects/$projectId/secret-manager/approval': typeof secretManagerSecretApprovalsPageRouteRoute - '/projects/$projectId/secret-manager/overview': typeof secretManagerOverviewPageRouteRoute - '/projects/$projectId/secret-manager/secret-rotation': typeof secretManagerSecretRotationPageRouteRoute - '/projects/$projectId/secret-manager/settings': typeof secretManagerSettingsPageRouteRoute - '/projects/$projectId/secret-scanning/findings': typeof secretScanningSecretScanningFindingsPageRouteRoute - '/projects/$projectId/secret-scanning/settings': typeof secretScanningSettingsPageRouteRoute - '/projects/$projectId/ssh/cas': typeof sshSshCasPageRouteRoute - '/projects/$projectId/ssh/certificates': typeof sshSshCertsPageRouteRoute - '/projects/$projectId/ssh/overview': typeof sshSshHostsPageRouteRoute - '/projects/$projectId/ssh/settings': typeof sshSettingsPageRouteRoute - '/projects/$projectId/cert-manager/certificate-templates': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutCertificateTemplatesRouteWithChildren - '/projects/$projectId/cert-manager/subscribers': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutSubscribersRouteWithChildren - '/projects/$projectId/secret-manager/integrations': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRouteWithChildren - '/projects/$projectId/secret-scanning/data-sources': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningSecretScanningLayoutDataSourcesRouteWithChildren - '/projects/$projectId/cert-manager/certificate-templates/': typeof certManagerPkiTemplateListPageRouteRoute - '/projects/$projectId/cert-manager/subscribers/': typeof certManagerPkiSubscribersPageRouteRoute - '/projects/$projectId/secret-manager/integrations/': typeof secretManagerIntegrationsListPageRouteRoute - '/projects/$projectId/secret-scanning/data-sources/': typeof secretScanningSecretScanningDataSourcesPageRouteRoute - '/projects/$projectId/cert-manager/ca/$caName': typeof certManagerCertAuthDetailsByIDPageRouteRoute - '/projects/$projectId/cert-manager/subscribers/$subscriberName': typeof certManagerPkiSubscriberDetailsByIDPageRouteRoute - '/projects/$projectId/secret-manager/integrations/$integrationId': typeof secretManagerIntegrationsDetailsByIDPageRouteRoute - '/projects/$projectId/secret-manager/integrations/select-integration-auth': typeof secretManagerIntegrationsSelectIntegrationAuthPageRouteRoute - '/projects/$projectId/secret-manager/secrets/$envSlug': typeof secretManagerSecretDashboardPageRouteRoute - '/projects/$projectId/ssh/ca/$caId': typeof sshSshCaByIDPageRouteRoute - '/projects/$projectId/ssh/ssh-host-groups/$sshHostGroupId': typeof sshSshHostGroupDetailsByIDPageRouteRoute - '/projects/$projectId/cert-manager/pki-collections/$collectionId': typeof certManagerPkiCollectionDetailsByIDPageRoutesRoute - '/projects/$projectId/integrations/azure-app-configuration/oauth2/callback': typeof secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectRoute - '/projects/$projectId/integrations/azure-key-vault/oauth2/callback': typeof secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectRoute - '/projects/$projectId/integrations/bitbucket/oauth2/callback': typeof secretManagerIntegrationsRouteBitbucketOauthRedirectRoute - '/projects/$projectId/integrations/gcp-secret-manager/oauth2/callback': typeof secretManagerIntegrationsRouteGcpOauthRedirectRoute - '/projects/$projectId/integrations/github/oauth2/callback': typeof secretManagerIntegrationsRouteGithubOauthRedirectRoute - '/projects/$projectId/integrations/gitlab/oauth2/callback': typeof secretManagerIntegrationsRouteGitlabOauthRedirectRoute - '/projects/$projectId/integrations/heroku/oauth2/callback': typeof secretManagerIntegrationsRouteHerokuOauthRedirectRoute - '/projects/$projectId/integrations/netlify/oauth2/callback': typeof secretManagerIntegrationsRouteNetlifyOauthRedirectRoute - '/projects/$projectId/integrations/vercel/oauth2/callback': typeof secretManagerIntegrationsRouteVercelOauthRedirectRoute - '/projects/$projectId/secret-manager/integrations/aws-parameter-store/authorize': typeof secretManagerIntegrationsAwsParameterStoreAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/aws-parameter-store/create': typeof secretManagerIntegrationsAwsParameterStoreConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/aws-secret-manager/authorize': typeof secretManagerIntegrationsAwsSecretManagerAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/aws-secret-manager/create': typeof secretManagerIntegrationsAwsSecretManagerConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/azure-app-configuration/create': typeof secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/azure-devops/authorize': typeof secretManagerIntegrationsAzureDevopsAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/azure-devops/create': typeof secretManagerIntegrationsAzureDevopsConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/azure-key-vault/authorize': typeof secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/azure-key-vault/create': typeof secretManagerIntegrationsAzureKeyVaultConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/bitbucket/create': typeof secretManagerIntegrationsBitbucketConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/checkly/authorize': typeof secretManagerIntegrationsChecklyAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/checkly/create': typeof secretManagerIntegrationsChecklyConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/circleci/authorize': typeof secretManagerIntegrationsCircleCIAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/circleci/create': typeof secretManagerIntegrationsCircleCIConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/cloud-66/authorize': typeof secretManagerIntegrationsCloud66AuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/cloud-66/create': typeof secretManagerIntegrationsCloud66ConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/cloudflare-pages/authorize': typeof secretManagerIntegrationsCloudflarePagesAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/cloudflare-pages/create': typeof secretManagerIntegrationsCloudflarePagesConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/cloudflare-workers/authorize': typeof secretManagerIntegrationsCloudflareWorkersAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/cloudflare-workers/create': typeof secretManagerIntegrationsCloudflareWorkersConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/codefresh/authorize': typeof secretManagerIntegrationsCodefreshAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/codefresh/create': typeof secretManagerIntegrationsCodefreshConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/databricks/authorize': typeof secretManagerIntegrationsDatabricksAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/databricks/create': typeof secretManagerIntegrationsDatabricksConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/digital-ocean-app-platform/authorize': typeof secretManagerIntegrationsDigitalOceanAppPlatformAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/digital-ocean-app-platform/create': typeof secretManagerIntegrationsDigitalOceanAppPlatformConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/flyio/authorize': typeof secretManagerIntegrationsFlyioAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/flyio/create': typeof secretManagerIntegrationsFlyioConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/gcp-secret-manager/authorize': typeof secretManagerIntegrationsGcpSecretManagerAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/gcp-secret-manager/create': typeof secretManagerIntegrationsGcpSecretManagerConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/github/auth-mode-selection': typeof secretManagerIntegrationsGithubAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/github/create': typeof secretManagerIntegrationsGithubConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/gitlab/authorize': typeof secretManagerIntegrationsGitlabAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/gitlab/create': typeof secretManagerIntegrationsGitlabConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/hashicorp-vault/authorize': typeof secretManagerIntegrationsHashicorpVaultAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/hashicorp-vault/create': typeof secretManagerIntegrationsHashicorpVaultConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/hasura-cloud/authorize': typeof secretManagerIntegrationsHasuraCloudAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/hasura-cloud/create': typeof secretManagerIntegrationsHasuraCloudConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/heroku/create': typeof secretManagerIntegrationsHerokuConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/laravel-forge/authorize': typeof secretManagerIntegrationsLaravelForgeAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/laravel-forge/create': typeof secretManagerIntegrationsLaravelForgeConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/netlify/create': typeof secretManagerIntegrationsNetlifyConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/northflank/authorize': typeof secretManagerIntegrationsNorthflankAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/northflank/create': typeof secretManagerIntegrationsNorthflankConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/octopus-deploy/authorize': typeof secretManagerIntegrationsOctopusDeployAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/octopus-deploy/create': typeof secretManagerIntegrationsOctopusDeployConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/qovery/authorize': typeof secretManagerIntegrationsQoveryAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/qovery/create': typeof secretManagerIntegrationsQoveryConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/railway/authorize': typeof secretManagerIntegrationsRailwayAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/railway/create': typeof secretManagerIntegrationsRailwayConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/render/authorize': typeof secretManagerIntegrationsRenderAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/render/create': typeof secretManagerIntegrationsRenderConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/rundeck/authorize': typeof secretManagerIntegrationsRundeckAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/rundeck/create': typeof secretManagerIntegrationsRundeckConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/supabase/authorize': typeof secretManagerIntegrationsSupabaseAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/supabase/create': typeof secretManagerIntegrationsSupabaseConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/teamcity/authorize': typeof secretManagerIntegrationsTeamcityAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/teamcity/create': typeof secretManagerIntegrationsTeamcityConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/terraform-cloud/authorize': typeof secretManagerIntegrationsTerraformCloudAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/terraform-cloud/create': typeof secretManagerIntegrationsTerraformCloudConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/travisci/authorize': typeof secretManagerIntegrationsTravisCIAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/travisci/create': typeof secretManagerIntegrationsTravisCIConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/vercel/create': typeof secretManagerIntegrationsVercelConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/windmill/authorize': typeof secretManagerIntegrationsWindmillAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/windmill/create': typeof secretManagerIntegrationsWindmillConfigurePageRouteRoute - '/projects/$projectId/secret-scanning/data-sources/$type/$dataSourceId': typeof secretScanningSecretScanningDataSourceByIdPageRouteRoute - '/projects/$projectId/secret-manager/commits/$environment/$folderId': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdRouteWithChildren - '/projects/$projectId/secret-manager/commits/$environment/$folderId/': typeof secretManagerCommitsPageRouteRoute - '/projects/$projectId/secret-manager/integrations/azure-app-configuration/oauth2/callback': typeof secretManagerIntegrationsAzureAppConfigurationOauthCallbackPageRouteRoute - '/projects/$projectId/secret-manager/integrations/azure-key-vault/oauth2/callback': typeof secretManagerIntegrationsAzureKeyVaultOauthCallbackPageRouteRoute - '/projects/$projectId/secret-manager/integrations/bitbucket/oauth2/callback': typeof secretManagerIntegrationsBitbucketOauthCallbackPageRouteRoute - '/projects/$projectId/secret-manager/integrations/gcp-secret-manager/oauth2/callback': typeof secretManagerIntegrationsGcpSecretManagerOauthCallbackPageRouteRoute - '/projects/$projectId/secret-manager/integrations/github/oauth2/callback': typeof secretManagerIntegrationsGithubOauthCallbackPageRouteRoute - '/projects/$projectId/secret-manager/integrations/gitlab/oauth2/callback': typeof secretManagerIntegrationsGitlabOauthCallbackPageRouteRoute - '/projects/$projectId/secret-manager/integrations/heroku/oauth2/callback': typeof secretManagerIntegrationsHerokuOauthCallbackPageRouteRoute - '/projects/$projectId/secret-manager/integrations/netlify/oauth2/callback': typeof secretManagerIntegrationsNetlifyOauthCallbackPageRouteRoute - '/projects/$projectId/secret-manager/integrations/secret-syncs/$destination/$syncId': typeof secretManagerSecretSyncDetailsByIDPageRouteRoute - '/projects/$projectId/secret-manager/integrations/vercel/oauth2/callback': typeof secretManagerIntegrationsVercelOauthCallbackPageRouteRoute - '/projects/$projectId/secret-manager/commits/$environment/$folderId/$commitId': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteWithChildren - '/projects/$projectId/secret-manager/commits/$environment/$folderId/$commitId/': typeof secretManagerCommitDetailsPageRouteRoute - '/projects/$projectId/secret-manager/commits/$environment/$folderId/$commitId/restore': typeof secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteRoute + '/projects/cert-management/$projectId/alerting': typeof certManagerAlertingPageRouteRoute + '/projects/cert-management/$projectId/certificate-authorities': typeof certManagerCertificateAuthoritiesPageRouteRoute + '/projects/cert-management/$projectId/certificates': typeof certManagerCertificatesPageRouteRoute + '/projects/cert-management/$projectId/settings': typeof certManagerSettingsPageRouteRoute + '/projects/kms/$projectId/kmip': typeof kmsKmipPageRouteRoute + '/projects/kms/$projectId/overview': typeof kmsOverviewPageRouteRoute + '/projects/kms/$projectId/settings': typeof kmsSettingsPageRouteRoute + '/projects/secret-management/$projectId/allowlist': typeof secretManagerIPAllowlistPageRouteRoute + '/projects/secret-management/$projectId/approval': typeof secretManagerSecretApprovalsPageRouteRoute + '/projects/secret-management/$projectId/overview': typeof secretManagerOverviewPageRouteRoute + '/projects/secret-management/$projectId/secret-rotation': typeof secretManagerSecretRotationPageRouteRoute + '/projects/secret-management/$projectId/settings': typeof secretManagerSettingsPageRouteRoute + '/projects/secret-scanning/$projectId/findings': typeof secretScanningSecretScanningFindingsPageRouteRoute + '/projects/secret-scanning/$projectId/settings': typeof secretScanningSettingsPageRouteRoute + '/projects/ssh/$projectId/cas': typeof sshSshCasPageRouteRoute + '/projects/ssh/$projectId/certificates': typeof sshSshCertsPageRouteRoute + '/projects/ssh/$projectId/overview': typeof sshSshHostsPageRouteRoute + '/projects/ssh/$projectId/settings': typeof sshSettingsPageRouteRoute + '/projects/cert-management/$projectId/access-management': typeof projectAccessControlPageRouteCertManagerRoute + '/projects/cert-management/$projectId/certificate-templates': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesRouteWithChildren + '/projects/cert-management/$projectId/subscribers': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutSubscribersRouteWithChildren + '/projects/kms/$projectId/access-management': typeof projectAccessControlPageRouteKmsRoute + '/projects/secret-management/$projectId/access-management': typeof projectAccessControlPageRouteSecretManagerRoute + '/projects/secret-management/$projectId/integrations': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRouteWithChildren + '/projects/secret-scanning/$projectId/access-management': typeof projectAccessControlPageRouteSecretScanningRoute + '/projects/secret-scanning/$projectId/data-sources': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRouteWithChildren + '/projects/ssh/$projectId/access-management': typeof projectAccessControlPageRouteSshRoute + '/projects/cert-management/$projectId/certificate-templates/': typeof certManagerPkiTemplateListPageRouteRoute + '/projects/cert-management/$projectId/subscribers/': typeof certManagerPkiSubscribersPageRouteRoute + '/projects/secret-management/$projectId/integrations/': typeof secretManagerIntegrationsListPageRouteRoute + '/projects/secret-scanning/$projectId/data-sources/': typeof secretScanningSecretScanningDataSourcesPageRouteRoute + '/projects/cert-management/$projectId/ca/$caName': typeof certManagerCertAuthDetailsByIDPageRouteRoute + '/projects/cert-management/$projectId/subscribers/$subscriberName': typeof certManagerPkiSubscriberDetailsByIDPageRouteRoute + '/projects/secret-management/$projectId/integrations/$integrationId': typeof secretManagerIntegrationsDetailsByIDPageRouteRoute + '/projects/secret-management/$projectId/integrations/select-integration-auth': typeof secretManagerIntegrationsSelectIntegrationAuthPageRouteRoute + '/projects/secret-management/$projectId/secrets/$envSlug': typeof secretManagerSecretDashboardPageRouteRoute + '/projects/ssh/$projectId/ca/$caId': typeof sshSshCaByIDPageRouteRoute + '/projects/ssh/$projectId/ssh-host-groups/$sshHostGroupId': typeof sshSshHostGroupDetailsByIDPageRouteRoute + '/projects/cert-management/$projectId/groups/$groupId': typeof projectGroupDetailsByIDPageRouteCertManagerRoute + '/projects/cert-management/$projectId/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteCertManagerRoute + '/projects/cert-management/$projectId/members/$membershipId': typeof projectMemberDetailsByIDPageRouteCertManagerRoute + '/projects/cert-management/$projectId/pki-collections/$collectionId': typeof certManagerPkiCollectionDetailsByIDPageRoutesRoute + '/projects/cert-management/$projectId/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteCertManagerRoute + '/projects/kms/$projectId/groups/$groupId': typeof projectGroupDetailsByIDPageRouteKmsRoute + '/projects/kms/$projectId/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteKmsRoute + '/projects/kms/$projectId/members/$membershipId': typeof projectMemberDetailsByIDPageRouteKmsRoute + '/projects/kms/$projectId/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteKmsRoute + '/projects/secret-management/$projectId/groups/$groupId': typeof projectGroupDetailsByIDPageRouteSecretManagerRoute + '/projects/secret-management/$projectId/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteSecretManagerRoute + '/projects/secret-management/$projectId/members/$membershipId': typeof projectMemberDetailsByIDPageRouteSecretManagerRoute + '/projects/secret-management/$projectId/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteSecretManagerRoute + '/projects/secret-scanning/$projectId/groups/$groupId': typeof projectGroupDetailsByIDPageRouteSecretScanningRoute + '/projects/secret-scanning/$projectId/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteSecretScanningRoute + '/projects/secret-scanning/$projectId/members/$membershipId': typeof projectMemberDetailsByIDPageRouteSecretScanningRoute + '/projects/secret-scanning/$projectId/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteSecretScanningRoute + '/projects/ssh/$projectId/groups/$groupId': typeof projectGroupDetailsByIDPageRouteSshRoute + '/projects/ssh/$projectId/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteSshRoute + '/projects/ssh/$projectId/members/$membershipId': typeof projectMemberDetailsByIDPageRouteSshRoute + '/projects/ssh/$projectId/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteSshRoute + '/projects/secret-management/$projectId/integrations/aws-parameter-store/authorize': typeof secretManagerIntegrationsAwsParameterStoreAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/aws-parameter-store/create': typeof secretManagerIntegrationsAwsParameterStoreConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/aws-secret-manager/authorize': typeof secretManagerIntegrationsAwsSecretManagerAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/aws-secret-manager/create': typeof secretManagerIntegrationsAwsSecretManagerConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/azure-app-configuration/create': typeof secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/azure-devops/authorize': typeof secretManagerIntegrationsAzureDevopsAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/azure-devops/create': typeof secretManagerIntegrationsAzureDevopsConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/azure-key-vault/authorize': typeof secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/azure-key-vault/create': typeof secretManagerIntegrationsAzureKeyVaultConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/bitbucket/create': typeof secretManagerIntegrationsBitbucketConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/checkly/authorize': typeof secretManagerIntegrationsChecklyAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/checkly/create': typeof secretManagerIntegrationsChecklyConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/circleci/authorize': typeof secretManagerIntegrationsCircleCIAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/circleci/create': typeof secretManagerIntegrationsCircleCIConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/cloud-66/authorize': typeof secretManagerIntegrationsCloud66AuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/cloud-66/create': typeof secretManagerIntegrationsCloud66ConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/cloudflare-pages/authorize': typeof secretManagerIntegrationsCloudflarePagesAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/cloudflare-pages/create': typeof secretManagerIntegrationsCloudflarePagesConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/cloudflare-workers/authorize': typeof secretManagerIntegrationsCloudflareWorkersAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/cloudflare-workers/create': typeof secretManagerIntegrationsCloudflareWorkersConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/codefresh/authorize': typeof secretManagerIntegrationsCodefreshAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/codefresh/create': typeof secretManagerIntegrationsCodefreshConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/databricks/authorize': typeof secretManagerIntegrationsDatabricksAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/databricks/create': typeof secretManagerIntegrationsDatabricksConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/authorize': typeof secretManagerIntegrationsDigitalOceanAppPlatformAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/create': typeof secretManagerIntegrationsDigitalOceanAppPlatformConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/flyio/authorize': typeof secretManagerIntegrationsFlyioAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/flyio/create': typeof secretManagerIntegrationsFlyioConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/gcp-secret-manager/authorize': typeof secretManagerIntegrationsGcpSecretManagerAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/gcp-secret-manager/create': typeof secretManagerIntegrationsGcpSecretManagerConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/github/auth-mode-selection': typeof secretManagerIntegrationsGithubAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/github/create': typeof secretManagerIntegrationsGithubConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/gitlab/authorize': typeof secretManagerIntegrationsGitlabAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/gitlab/create': typeof secretManagerIntegrationsGitlabConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/hashicorp-vault/authorize': typeof secretManagerIntegrationsHashicorpVaultAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/hashicorp-vault/create': typeof secretManagerIntegrationsHashicorpVaultConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/hasura-cloud/authorize': typeof secretManagerIntegrationsHasuraCloudAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/hasura-cloud/create': typeof secretManagerIntegrationsHasuraCloudConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/heroku/create': typeof secretManagerIntegrationsHerokuConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/laravel-forge/authorize': typeof secretManagerIntegrationsLaravelForgeAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/laravel-forge/create': typeof secretManagerIntegrationsLaravelForgeConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/netlify/create': typeof secretManagerIntegrationsNetlifyConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/northflank/authorize': typeof secretManagerIntegrationsNorthflankAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/northflank/create': typeof secretManagerIntegrationsNorthflankConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/octopus-deploy/authorize': typeof secretManagerIntegrationsOctopusDeployAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/octopus-deploy/create': typeof secretManagerIntegrationsOctopusDeployConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/qovery/authorize': typeof secretManagerIntegrationsQoveryAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/qovery/create': typeof secretManagerIntegrationsQoveryConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/railway/authorize': typeof secretManagerIntegrationsRailwayAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/railway/create': typeof secretManagerIntegrationsRailwayConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/render/authorize': typeof secretManagerIntegrationsRenderAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/render/create': typeof secretManagerIntegrationsRenderConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/rundeck/authorize': typeof secretManagerIntegrationsRundeckAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/rundeck/create': typeof secretManagerIntegrationsRundeckConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/supabase/authorize': typeof secretManagerIntegrationsSupabaseAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/supabase/create': typeof secretManagerIntegrationsSupabaseConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/teamcity/authorize': typeof secretManagerIntegrationsTeamcityAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/teamcity/create': typeof secretManagerIntegrationsTeamcityConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/terraform-cloud/authorize': typeof secretManagerIntegrationsTerraformCloudAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/terraform-cloud/create': typeof secretManagerIntegrationsTerraformCloudConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/travisci/authorize': typeof secretManagerIntegrationsTravisCIAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/travisci/create': typeof secretManagerIntegrationsTravisCIConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/vercel/create': typeof secretManagerIntegrationsVercelConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/windmill/authorize': typeof secretManagerIntegrationsWindmillAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/windmill/create': typeof secretManagerIntegrationsWindmillConfigurePageRouteRoute + '/projects/secret-scanning/$projectId/data-sources/$type/$dataSourceId': typeof secretScanningSecretScanningDataSourceByIdPageRouteRoute + '/projects/secret-management/$projectId/commits/$environment/$folderId': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRouteWithChildren + '/projects/secret-management/$projectId/commits/$environment/$folderId/': typeof secretManagerCommitsPageRouteRoute + '/projects/secret-management/$projectId/integrations/azure-app-configuration/oauth2/callback': typeof secretManagerIntegrationsAzureAppConfigurationOauthCallbackPageRouteRoute + '/projects/secret-management/$projectId/integrations/azure-key-vault/oauth2/callback': typeof secretManagerIntegrationsAzureKeyVaultOauthCallbackPageRouteRoute + '/projects/secret-management/$projectId/integrations/bitbucket/oauth2/callback': typeof secretManagerIntegrationsBitbucketOauthCallbackPageRouteRoute + '/projects/secret-management/$projectId/integrations/gcp-secret-manager/oauth2/callback': typeof secretManagerIntegrationsGcpSecretManagerOauthCallbackPageRouteRoute + '/projects/secret-management/$projectId/integrations/github/oauth2/callback': typeof secretManagerIntegrationsGithubOauthCallbackPageRouteRoute + '/projects/secret-management/$projectId/integrations/gitlab/oauth2/callback': typeof secretManagerIntegrationsGitlabOauthCallbackPageRouteRoute + '/projects/secret-management/$projectId/integrations/heroku/oauth2/callback': typeof secretManagerIntegrationsHerokuOauthCallbackPageRouteRoute + '/projects/secret-management/$projectId/integrations/netlify/oauth2/callback': typeof secretManagerIntegrationsNetlifyOauthCallbackPageRouteRoute + '/projects/secret-management/$projectId/integrations/secret-syncs/$destination/$syncId': typeof secretManagerSecretSyncDetailsByIDPageRouteRoute + '/projects/secret-management/$projectId/integrations/vercel/oauth2/callback': typeof secretManagerIntegrationsVercelOauthCallbackPageRouteRoute + '/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteWithChildren + '/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId/': typeof secretManagerCommitDetailsPageRouteRoute + '/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId/restore': typeof secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteRoute } export interface FileRoutesByTo { @@ -4519,6 +4791,7 @@ export interface FileRoutesByTo { '/admin': typeof adminGeneralPageRouteRoute '/login/provider/error': typeof authProviderErrorPageRouteRoute '/login/provider/success': typeof authProviderSuccessPageRouteRoute + '/integrations': typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRouteWithChildren '/organization': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationRouteWithChildren '/organization/access-management': typeof organizationAccessManagementPageRouteRoute '/organization/admin': typeof organizationAdminPageRouteRoute @@ -4530,7 +4803,6 @@ export interface FileRoutesByTo { '/admin/encryption': typeof adminEncryptionPageRouteRoute '/admin/environment': typeof adminEnvironmentPageRouteRoute '/admin/integrations': typeof adminIntegrationsPageRouteRoute - '/projects/$projectId': typeof projectLayoutGeneralRouteWithChildren '/secret-manager/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRouteWithChildren '/organization/app-connections': typeof organizationAppConnectionsAppConnectionsPageRouteRoute '/organization/gateways': typeof organizationGatewaysGatewayListPageRouteRoute @@ -4544,139 +4816,157 @@ export interface FileRoutesByTo { '/admin/resources/machine-identities': typeof adminMachineIdentitiesResourcesPageRouteRoute '/admin/resources/organizations': typeof adminOrganizationResourcesPageRouteRoute '/admin/resources/user-identities': typeof adminUserIdentitiesResourcesPageRouteRoute + '/projects/cert-management/$projectId': typeof certManagerLayoutRouteWithChildren + '/projects/kms/$projectId': typeof kmsLayoutRouteWithChildren + '/projects/secret-management/$projectId': typeof secretManagerLayoutRouteWithChildren + '/projects/secret-scanning/$projectId': typeof secretScanningLayoutRouteWithChildren + '/projects/ssh/$projectId': typeof sshLayoutRouteWithChildren '/secret-manager/$projectId/approval': typeof secretManagerRedirectsRedirectApprovalPageRoute '/organization/settings/oauth/callback': typeof organizationSettingsPageOauthCallbackPageRouteRoute - '/projects/$projectId/cert-manager': typeof certManagerLayoutRouteWithChildren - '/projects/$projectId/integrations': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsRouteWithChildren - '/projects/$projectId/kms': typeof kmsLayoutRouteWithChildren - '/projects/$projectId/secret-manager': typeof secretManagerLayoutRouteWithChildren - '/projects/$projectId/secret-scanning': typeof secretScanningLayoutRouteWithChildren - '/projects/$projectId/ssh': typeof sshLayoutRouteWithChildren + '/integrations/azure-app-configuration/oauth2/callback': typeof secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectRoute + '/integrations/azure-key-vault/oauth2/callback': typeof secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectRoute + '/integrations/bitbucket/oauth2/callback': typeof secretManagerIntegrationsRouteBitbucketOauthRedirectRoute + '/integrations/gcp-secret-manager/oauth2/callback': typeof secretManagerIntegrationsRouteGcpOauthRedirectRoute + '/integrations/github/oauth2/callback': typeof secretManagerIntegrationsRouteGithubOauthRedirectRoute + '/integrations/gitlab/oauth2/callback': typeof secretManagerIntegrationsRouteGitlabOauthRedirectRoute + '/integrations/heroku/oauth2/callback': typeof secretManagerIntegrationsRouteHerokuOauthRedirectRoute + '/integrations/netlify/oauth2/callback': typeof secretManagerIntegrationsRouteNetlifyOauthRedirectRoute + '/integrations/vercel/oauth2/callback': typeof secretManagerIntegrationsRouteVercelOauthRedirectRoute '/organization/app-connections/$appConnection/oauth/callback': typeof organizationAppConnectionsOauthCallbackPageRouteRoute - '/projects/$projectId/access-management': typeof projectAccessControlPageRouteRoute - '/projects/$projectId/settings': typeof projectSettingsPageRouteRoute - '/projects/$projectId/groups/$groupId': typeof projectGroupDetailsByIDPageRouteRoute - '/projects/$projectId/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteRoute - '/projects/$projectId/members/$membershipId': typeof projectMemberDetailsByIDPageRouteRoute - '/projects/$projectId/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteRoute - '/projects/$projectId/cert-manager/alerting': typeof certManagerAlertingPageRouteRoute - '/projects/$projectId/cert-manager/certificate-authorities': typeof certManagerCertificateAuthoritiesPageRouteRoute - '/projects/$projectId/cert-manager/certificates': typeof certManagerCertificatesPageRouteRoute - '/projects/$projectId/cert-manager/settings': typeof certManagerSettingsPageRouteRoute - '/projects/$projectId/kms/kmip': typeof kmsKmipPageRouteRoute - '/projects/$projectId/kms/overview': typeof kmsOverviewPageRouteRoute - '/projects/$projectId/kms/settings': typeof kmsSettingsPageRouteRoute - '/projects/$projectId/secret-manager/allowlist': typeof secretManagerIPAllowlistPageRouteRoute - '/projects/$projectId/secret-manager/approval': typeof secretManagerSecretApprovalsPageRouteRoute - '/projects/$projectId/secret-manager/overview': typeof secretManagerOverviewPageRouteRoute - '/projects/$projectId/secret-manager/secret-rotation': typeof secretManagerSecretRotationPageRouteRoute - '/projects/$projectId/secret-manager/settings': typeof secretManagerSettingsPageRouteRoute - '/projects/$projectId/secret-scanning/findings': typeof secretScanningSecretScanningFindingsPageRouteRoute - '/projects/$projectId/secret-scanning/settings': typeof secretScanningSettingsPageRouteRoute - '/projects/$projectId/ssh/cas': typeof sshSshCasPageRouteRoute - '/projects/$projectId/ssh/certificates': typeof sshSshCertsPageRouteRoute - '/projects/$projectId/ssh/overview': typeof sshSshHostsPageRouteRoute - '/projects/$projectId/ssh/settings': typeof sshSettingsPageRouteRoute - '/projects/$projectId/cert-manager/certificate-templates': typeof certManagerPkiTemplateListPageRouteRoute - '/projects/$projectId/cert-manager/subscribers': typeof certManagerPkiSubscribersPageRouteRoute - '/projects/$projectId/secret-manager/integrations': typeof secretManagerIntegrationsListPageRouteRoute - '/projects/$projectId/secret-scanning/data-sources': typeof secretScanningSecretScanningDataSourcesPageRouteRoute - '/projects/$projectId/cert-manager/ca/$caName': typeof certManagerCertAuthDetailsByIDPageRouteRoute - '/projects/$projectId/cert-manager/subscribers/$subscriberName': typeof certManagerPkiSubscriberDetailsByIDPageRouteRoute - '/projects/$projectId/secret-manager/integrations/$integrationId': typeof secretManagerIntegrationsDetailsByIDPageRouteRoute - '/projects/$projectId/secret-manager/integrations/select-integration-auth': typeof secretManagerIntegrationsSelectIntegrationAuthPageRouteRoute - '/projects/$projectId/secret-manager/secrets/$envSlug': typeof secretManagerSecretDashboardPageRouteRoute - '/projects/$projectId/ssh/ca/$caId': typeof sshSshCaByIDPageRouteRoute - '/projects/$projectId/ssh/ssh-host-groups/$sshHostGroupId': typeof sshSshHostGroupDetailsByIDPageRouteRoute - '/projects/$projectId/cert-manager/pki-collections/$collectionId': typeof certManagerPkiCollectionDetailsByIDPageRoutesRoute - '/projects/$projectId/integrations/azure-app-configuration/oauth2/callback': typeof secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectRoute - '/projects/$projectId/integrations/azure-key-vault/oauth2/callback': typeof secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectRoute - '/projects/$projectId/integrations/bitbucket/oauth2/callback': typeof secretManagerIntegrationsRouteBitbucketOauthRedirectRoute - '/projects/$projectId/integrations/gcp-secret-manager/oauth2/callback': typeof secretManagerIntegrationsRouteGcpOauthRedirectRoute - '/projects/$projectId/integrations/github/oauth2/callback': typeof secretManagerIntegrationsRouteGithubOauthRedirectRoute - '/projects/$projectId/integrations/gitlab/oauth2/callback': typeof secretManagerIntegrationsRouteGitlabOauthRedirectRoute - '/projects/$projectId/integrations/heroku/oauth2/callback': typeof secretManagerIntegrationsRouteHerokuOauthRedirectRoute - '/projects/$projectId/integrations/netlify/oauth2/callback': typeof secretManagerIntegrationsRouteNetlifyOauthRedirectRoute - '/projects/$projectId/integrations/vercel/oauth2/callback': typeof secretManagerIntegrationsRouteVercelOauthRedirectRoute - '/projects/$projectId/secret-manager/integrations/aws-parameter-store/authorize': typeof secretManagerIntegrationsAwsParameterStoreAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/aws-parameter-store/create': typeof secretManagerIntegrationsAwsParameterStoreConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/aws-secret-manager/authorize': typeof secretManagerIntegrationsAwsSecretManagerAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/aws-secret-manager/create': typeof secretManagerIntegrationsAwsSecretManagerConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/azure-app-configuration/create': typeof secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/azure-devops/authorize': typeof secretManagerIntegrationsAzureDevopsAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/azure-devops/create': typeof secretManagerIntegrationsAzureDevopsConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/azure-key-vault/authorize': typeof secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/azure-key-vault/create': typeof secretManagerIntegrationsAzureKeyVaultConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/bitbucket/create': typeof secretManagerIntegrationsBitbucketConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/checkly/authorize': typeof secretManagerIntegrationsChecklyAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/checkly/create': typeof secretManagerIntegrationsChecklyConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/circleci/authorize': typeof secretManagerIntegrationsCircleCIAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/circleci/create': typeof secretManagerIntegrationsCircleCIConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/cloud-66/authorize': typeof secretManagerIntegrationsCloud66AuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/cloud-66/create': typeof secretManagerIntegrationsCloud66ConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/cloudflare-pages/authorize': typeof secretManagerIntegrationsCloudflarePagesAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/cloudflare-pages/create': typeof secretManagerIntegrationsCloudflarePagesConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/cloudflare-workers/authorize': typeof secretManagerIntegrationsCloudflareWorkersAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/cloudflare-workers/create': typeof secretManagerIntegrationsCloudflareWorkersConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/codefresh/authorize': typeof secretManagerIntegrationsCodefreshAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/codefresh/create': typeof secretManagerIntegrationsCodefreshConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/databricks/authorize': typeof secretManagerIntegrationsDatabricksAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/databricks/create': typeof secretManagerIntegrationsDatabricksConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/digital-ocean-app-platform/authorize': typeof secretManagerIntegrationsDigitalOceanAppPlatformAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/digital-ocean-app-platform/create': typeof secretManagerIntegrationsDigitalOceanAppPlatformConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/flyio/authorize': typeof secretManagerIntegrationsFlyioAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/flyio/create': typeof secretManagerIntegrationsFlyioConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/gcp-secret-manager/authorize': typeof secretManagerIntegrationsGcpSecretManagerAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/gcp-secret-manager/create': typeof secretManagerIntegrationsGcpSecretManagerConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/github/auth-mode-selection': typeof secretManagerIntegrationsGithubAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/github/create': typeof secretManagerIntegrationsGithubConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/gitlab/authorize': typeof secretManagerIntegrationsGitlabAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/gitlab/create': typeof secretManagerIntegrationsGitlabConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/hashicorp-vault/authorize': typeof secretManagerIntegrationsHashicorpVaultAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/hashicorp-vault/create': typeof secretManagerIntegrationsHashicorpVaultConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/hasura-cloud/authorize': typeof secretManagerIntegrationsHasuraCloudAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/hasura-cloud/create': typeof secretManagerIntegrationsHasuraCloudConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/heroku/create': typeof secretManagerIntegrationsHerokuConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/laravel-forge/authorize': typeof secretManagerIntegrationsLaravelForgeAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/laravel-forge/create': typeof secretManagerIntegrationsLaravelForgeConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/netlify/create': typeof secretManagerIntegrationsNetlifyConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/northflank/authorize': typeof secretManagerIntegrationsNorthflankAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/northflank/create': typeof secretManagerIntegrationsNorthflankConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/octopus-deploy/authorize': typeof secretManagerIntegrationsOctopusDeployAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/octopus-deploy/create': typeof secretManagerIntegrationsOctopusDeployConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/qovery/authorize': typeof secretManagerIntegrationsQoveryAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/qovery/create': typeof secretManagerIntegrationsQoveryConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/railway/authorize': typeof secretManagerIntegrationsRailwayAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/railway/create': typeof secretManagerIntegrationsRailwayConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/render/authorize': typeof secretManagerIntegrationsRenderAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/render/create': typeof secretManagerIntegrationsRenderConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/rundeck/authorize': typeof secretManagerIntegrationsRundeckAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/rundeck/create': typeof secretManagerIntegrationsRundeckConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/supabase/authorize': typeof secretManagerIntegrationsSupabaseAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/supabase/create': typeof secretManagerIntegrationsSupabaseConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/teamcity/authorize': typeof secretManagerIntegrationsTeamcityAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/teamcity/create': typeof secretManagerIntegrationsTeamcityConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/terraform-cloud/authorize': typeof secretManagerIntegrationsTerraformCloudAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/terraform-cloud/create': typeof secretManagerIntegrationsTerraformCloudConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/travisci/authorize': typeof secretManagerIntegrationsTravisCIAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/travisci/create': typeof secretManagerIntegrationsTravisCIConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/vercel/create': typeof secretManagerIntegrationsVercelConfigurePageRouteRoute - '/projects/$projectId/secret-manager/integrations/windmill/authorize': typeof secretManagerIntegrationsWindmillAuthorizePageRouteRoute - '/projects/$projectId/secret-manager/integrations/windmill/create': typeof secretManagerIntegrationsWindmillConfigurePageRouteRoute - '/projects/$projectId/secret-scanning/data-sources/$type/$dataSourceId': typeof secretScanningSecretScanningDataSourceByIdPageRouteRoute - '/projects/$projectId/secret-manager/commits/$environment/$folderId': typeof secretManagerCommitsPageRouteRoute - '/projects/$projectId/secret-manager/integrations/azure-app-configuration/oauth2/callback': typeof secretManagerIntegrationsAzureAppConfigurationOauthCallbackPageRouteRoute - '/projects/$projectId/secret-manager/integrations/azure-key-vault/oauth2/callback': typeof secretManagerIntegrationsAzureKeyVaultOauthCallbackPageRouteRoute - '/projects/$projectId/secret-manager/integrations/bitbucket/oauth2/callback': typeof secretManagerIntegrationsBitbucketOauthCallbackPageRouteRoute - '/projects/$projectId/secret-manager/integrations/gcp-secret-manager/oauth2/callback': typeof secretManagerIntegrationsGcpSecretManagerOauthCallbackPageRouteRoute - '/projects/$projectId/secret-manager/integrations/github/oauth2/callback': typeof secretManagerIntegrationsGithubOauthCallbackPageRouteRoute - '/projects/$projectId/secret-manager/integrations/gitlab/oauth2/callback': typeof secretManagerIntegrationsGitlabOauthCallbackPageRouteRoute - '/projects/$projectId/secret-manager/integrations/heroku/oauth2/callback': typeof secretManagerIntegrationsHerokuOauthCallbackPageRouteRoute - '/projects/$projectId/secret-manager/integrations/netlify/oauth2/callback': typeof secretManagerIntegrationsNetlifyOauthCallbackPageRouteRoute - '/projects/$projectId/secret-manager/integrations/secret-syncs/$destination/$syncId': typeof secretManagerSecretSyncDetailsByIDPageRouteRoute - '/projects/$projectId/secret-manager/integrations/vercel/oauth2/callback': typeof secretManagerIntegrationsVercelOauthCallbackPageRouteRoute - '/projects/$projectId/secret-manager/commits/$environment/$folderId/$commitId': typeof secretManagerCommitDetailsPageRouteRoute - '/projects/$projectId/secret-manager/commits/$environment/$folderId/$commitId/restore': typeof secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteRoute + '/projects/cert-management/$projectId/alerting': typeof certManagerAlertingPageRouteRoute + '/projects/cert-management/$projectId/certificate-authorities': typeof certManagerCertificateAuthoritiesPageRouteRoute + '/projects/cert-management/$projectId/certificates': typeof certManagerCertificatesPageRouteRoute + '/projects/cert-management/$projectId/settings': typeof certManagerSettingsPageRouteRoute + '/projects/kms/$projectId/kmip': typeof kmsKmipPageRouteRoute + '/projects/kms/$projectId/overview': typeof kmsOverviewPageRouteRoute + '/projects/kms/$projectId/settings': typeof kmsSettingsPageRouteRoute + '/projects/secret-management/$projectId/allowlist': typeof secretManagerIPAllowlistPageRouteRoute + '/projects/secret-management/$projectId/approval': typeof secretManagerSecretApprovalsPageRouteRoute + '/projects/secret-management/$projectId/overview': typeof secretManagerOverviewPageRouteRoute + '/projects/secret-management/$projectId/secret-rotation': typeof secretManagerSecretRotationPageRouteRoute + '/projects/secret-management/$projectId/settings': typeof secretManagerSettingsPageRouteRoute + '/projects/secret-scanning/$projectId/findings': typeof secretScanningSecretScanningFindingsPageRouteRoute + '/projects/secret-scanning/$projectId/settings': typeof secretScanningSettingsPageRouteRoute + '/projects/ssh/$projectId/cas': typeof sshSshCasPageRouteRoute + '/projects/ssh/$projectId/certificates': typeof sshSshCertsPageRouteRoute + '/projects/ssh/$projectId/overview': typeof sshSshHostsPageRouteRoute + '/projects/ssh/$projectId/settings': typeof sshSettingsPageRouteRoute + '/projects/cert-management/$projectId/access-management': typeof projectAccessControlPageRouteCertManagerRoute + '/projects/kms/$projectId/access-management': typeof projectAccessControlPageRouteKmsRoute + '/projects/secret-management/$projectId/access-management': typeof projectAccessControlPageRouteSecretManagerRoute + '/projects/secret-scanning/$projectId/access-management': typeof projectAccessControlPageRouteSecretScanningRoute + '/projects/ssh/$projectId/access-management': typeof projectAccessControlPageRouteSshRoute + '/projects/cert-management/$projectId/certificate-templates': typeof certManagerPkiTemplateListPageRouteRoute + '/projects/cert-management/$projectId/subscribers': typeof certManagerPkiSubscribersPageRouteRoute + '/projects/secret-management/$projectId/integrations': typeof secretManagerIntegrationsListPageRouteRoute + '/projects/secret-scanning/$projectId/data-sources': typeof secretScanningSecretScanningDataSourcesPageRouteRoute + '/projects/cert-management/$projectId/ca/$caName': typeof certManagerCertAuthDetailsByIDPageRouteRoute + '/projects/cert-management/$projectId/subscribers/$subscriberName': typeof certManagerPkiSubscriberDetailsByIDPageRouteRoute + '/projects/secret-management/$projectId/integrations/$integrationId': typeof secretManagerIntegrationsDetailsByIDPageRouteRoute + '/projects/secret-management/$projectId/integrations/select-integration-auth': typeof secretManagerIntegrationsSelectIntegrationAuthPageRouteRoute + '/projects/secret-management/$projectId/secrets/$envSlug': typeof secretManagerSecretDashboardPageRouteRoute + '/projects/ssh/$projectId/ca/$caId': typeof sshSshCaByIDPageRouteRoute + '/projects/ssh/$projectId/ssh-host-groups/$sshHostGroupId': typeof sshSshHostGroupDetailsByIDPageRouteRoute + '/projects/cert-management/$projectId/groups/$groupId': typeof projectGroupDetailsByIDPageRouteCertManagerRoute + '/projects/cert-management/$projectId/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteCertManagerRoute + '/projects/cert-management/$projectId/members/$membershipId': typeof projectMemberDetailsByIDPageRouteCertManagerRoute + '/projects/cert-management/$projectId/pki-collections/$collectionId': typeof certManagerPkiCollectionDetailsByIDPageRoutesRoute + '/projects/cert-management/$projectId/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteCertManagerRoute + '/projects/kms/$projectId/groups/$groupId': typeof projectGroupDetailsByIDPageRouteKmsRoute + '/projects/kms/$projectId/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteKmsRoute + '/projects/kms/$projectId/members/$membershipId': typeof projectMemberDetailsByIDPageRouteKmsRoute + '/projects/kms/$projectId/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteKmsRoute + '/projects/secret-management/$projectId/groups/$groupId': typeof projectGroupDetailsByIDPageRouteSecretManagerRoute + '/projects/secret-management/$projectId/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteSecretManagerRoute + '/projects/secret-management/$projectId/members/$membershipId': typeof projectMemberDetailsByIDPageRouteSecretManagerRoute + '/projects/secret-management/$projectId/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteSecretManagerRoute + '/projects/secret-scanning/$projectId/groups/$groupId': typeof projectGroupDetailsByIDPageRouteSecretScanningRoute + '/projects/secret-scanning/$projectId/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteSecretScanningRoute + '/projects/secret-scanning/$projectId/members/$membershipId': typeof projectMemberDetailsByIDPageRouteSecretScanningRoute + '/projects/secret-scanning/$projectId/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteSecretScanningRoute + '/projects/ssh/$projectId/groups/$groupId': typeof projectGroupDetailsByIDPageRouteSshRoute + '/projects/ssh/$projectId/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteSshRoute + '/projects/ssh/$projectId/members/$membershipId': typeof projectMemberDetailsByIDPageRouteSshRoute + '/projects/ssh/$projectId/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteSshRoute + '/projects/secret-management/$projectId/integrations/aws-parameter-store/authorize': typeof secretManagerIntegrationsAwsParameterStoreAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/aws-parameter-store/create': typeof secretManagerIntegrationsAwsParameterStoreConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/aws-secret-manager/authorize': typeof secretManagerIntegrationsAwsSecretManagerAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/aws-secret-manager/create': typeof secretManagerIntegrationsAwsSecretManagerConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/azure-app-configuration/create': typeof secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/azure-devops/authorize': typeof secretManagerIntegrationsAzureDevopsAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/azure-devops/create': typeof secretManagerIntegrationsAzureDevopsConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/azure-key-vault/authorize': typeof secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/azure-key-vault/create': typeof secretManagerIntegrationsAzureKeyVaultConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/bitbucket/create': typeof secretManagerIntegrationsBitbucketConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/checkly/authorize': typeof secretManagerIntegrationsChecklyAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/checkly/create': typeof secretManagerIntegrationsChecklyConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/circleci/authorize': typeof secretManagerIntegrationsCircleCIAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/circleci/create': typeof secretManagerIntegrationsCircleCIConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/cloud-66/authorize': typeof secretManagerIntegrationsCloud66AuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/cloud-66/create': typeof secretManagerIntegrationsCloud66ConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/cloudflare-pages/authorize': typeof secretManagerIntegrationsCloudflarePagesAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/cloudflare-pages/create': typeof secretManagerIntegrationsCloudflarePagesConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/cloudflare-workers/authorize': typeof secretManagerIntegrationsCloudflareWorkersAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/cloudflare-workers/create': typeof secretManagerIntegrationsCloudflareWorkersConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/codefresh/authorize': typeof secretManagerIntegrationsCodefreshAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/codefresh/create': typeof secretManagerIntegrationsCodefreshConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/databricks/authorize': typeof secretManagerIntegrationsDatabricksAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/databricks/create': typeof secretManagerIntegrationsDatabricksConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/authorize': typeof secretManagerIntegrationsDigitalOceanAppPlatformAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/create': typeof secretManagerIntegrationsDigitalOceanAppPlatformConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/flyio/authorize': typeof secretManagerIntegrationsFlyioAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/flyio/create': typeof secretManagerIntegrationsFlyioConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/gcp-secret-manager/authorize': typeof secretManagerIntegrationsGcpSecretManagerAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/gcp-secret-manager/create': typeof secretManagerIntegrationsGcpSecretManagerConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/github/auth-mode-selection': typeof secretManagerIntegrationsGithubAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/github/create': typeof secretManagerIntegrationsGithubConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/gitlab/authorize': typeof secretManagerIntegrationsGitlabAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/gitlab/create': typeof secretManagerIntegrationsGitlabConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/hashicorp-vault/authorize': typeof secretManagerIntegrationsHashicorpVaultAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/hashicorp-vault/create': typeof secretManagerIntegrationsHashicorpVaultConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/hasura-cloud/authorize': typeof secretManagerIntegrationsHasuraCloudAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/hasura-cloud/create': typeof secretManagerIntegrationsHasuraCloudConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/heroku/create': typeof secretManagerIntegrationsHerokuConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/laravel-forge/authorize': typeof secretManagerIntegrationsLaravelForgeAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/laravel-forge/create': typeof secretManagerIntegrationsLaravelForgeConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/netlify/create': typeof secretManagerIntegrationsNetlifyConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/northflank/authorize': typeof secretManagerIntegrationsNorthflankAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/northflank/create': typeof secretManagerIntegrationsNorthflankConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/octopus-deploy/authorize': typeof secretManagerIntegrationsOctopusDeployAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/octopus-deploy/create': typeof secretManagerIntegrationsOctopusDeployConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/qovery/authorize': typeof secretManagerIntegrationsQoveryAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/qovery/create': typeof secretManagerIntegrationsQoveryConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/railway/authorize': typeof secretManagerIntegrationsRailwayAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/railway/create': typeof secretManagerIntegrationsRailwayConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/render/authorize': typeof secretManagerIntegrationsRenderAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/render/create': typeof secretManagerIntegrationsRenderConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/rundeck/authorize': typeof secretManagerIntegrationsRundeckAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/rundeck/create': typeof secretManagerIntegrationsRundeckConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/supabase/authorize': typeof secretManagerIntegrationsSupabaseAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/supabase/create': typeof secretManagerIntegrationsSupabaseConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/teamcity/authorize': typeof secretManagerIntegrationsTeamcityAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/teamcity/create': typeof secretManagerIntegrationsTeamcityConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/terraform-cloud/authorize': typeof secretManagerIntegrationsTerraformCloudAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/terraform-cloud/create': typeof secretManagerIntegrationsTerraformCloudConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/travisci/authorize': typeof secretManagerIntegrationsTravisCIAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/travisci/create': typeof secretManagerIntegrationsTravisCIConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/vercel/create': typeof secretManagerIntegrationsVercelConfigurePageRouteRoute + '/projects/secret-management/$projectId/integrations/windmill/authorize': typeof secretManagerIntegrationsWindmillAuthorizePageRouteRoute + '/projects/secret-management/$projectId/integrations/windmill/create': typeof secretManagerIntegrationsWindmillConfigurePageRouteRoute + '/projects/secret-scanning/$projectId/data-sources/$type/$dataSourceId': typeof secretScanningSecretScanningDataSourceByIdPageRouteRoute + '/projects/secret-management/$projectId/commits/$environment/$folderId': typeof secretManagerCommitsPageRouteRoute + '/projects/secret-management/$projectId/integrations/azure-app-configuration/oauth2/callback': typeof secretManagerIntegrationsAzureAppConfigurationOauthCallbackPageRouteRoute + '/projects/secret-management/$projectId/integrations/azure-key-vault/oauth2/callback': typeof secretManagerIntegrationsAzureKeyVaultOauthCallbackPageRouteRoute + '/projects/secret-management/$projectId/integrations/bitbucket/oauth2/callback': typeof secretManagerIntegrationsBitbucketOauthCallbackPageRouteRoute + '/projects/secret-management/$projectId/integrations/gcp-secret-manager/oauth2/callback': typeof secretManagerIntegrationsGcpSecretManagerOauthCallbackPageRouteRoute + '/projects/secret-management/$projectId/integrations/github/oauth2/callback': typeof secretManagerIntegrationsGithubOauthCallbackPageRouteRoute + '/projects/secret-management/$projectId/integrations/gitlab/oauth2/callback': typeof secretManagerIntegrationsGitlabOauthCallbackPageRouteRoute + '/projects/secret-management/$projectId/integrations/heroku/oauth2/callback': typeof secretManagerIntegrationsHerokuOauthCallbackPageRouteRoute + '/projects/secret-management/$projectId/integrations/netlify/oauth2/callback': typeof secretManagerIntegrationsNetlifyOauthCallbackPageRouteRoute + '/projects/secret-management/$projectId/integrations/secret-syncs/$destination/$syncId': typeof secretManagerSecretSyncDetailsByIDPageRouteRoute + '/projects/secret-management/$projectId/integrations/vercel/oauth2/callback': typeof secretManagerIntegrationsVercelOauthCallbackPageRouteRoute + '/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId': typeof secretManagerCommitDetailsPageRouteRoute + '/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId/restore': typeof secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteRoute } export interface FileRoutesById { @@ -4713,6 +5003,7 @@ export interface FileRoutesById { '/_authenticate/personal-settings/_layout/': typeof userPersonalSettingsPageRouteRoute '/_restrict-login-signup/login/provider/error': typeof authProviderErrorPageRouteRoute '/_restrict-login-signup/login/provider/success': typeof authProviderSuccessPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/integrations': typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRouteWithChildren '/_authenticate/_inject-org-details/_org-layout/organization': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationRouteWithChildren '/_authenticate/_inject-org-details/admin/_admin-layout': typeof adminLayoutRouteWithChildren '/_authenticate/_inject-org-details/admin/_admin-layout/': typeof adminGeneralPageRouteRoute @@ -4730,7 +5021,6 @@ export interface FileRoutesById { '/_authenticate/_inject-org-details/_org-layout/organization/gateways': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRouteWithChildren '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteWithChildren '/_authenticate/_inject-org-details/_org-layout/organization/settings': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSettingsRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdRouteWithChildren '/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRouteWithChildren '/_authenticate/_inject-org-details/_org-layout/organization/app-connections/': typeof organizationAppConnectionsAppConnectionsPageRouteRoute '/_authenticate/_inject-org-details/_org-layout/organization/gateways/': typeof organizationGatewaysGatewayListPageRouteRoute @@ -4744,152 +5034,168 @@ export interface FileRoutesById { '/_authenticate/_inject-org-details/admin/_admin-layout/resources/machine-identities': typeof adminMachineIdentitiesResourcesPageRouteRoute '/_authenticate/_inject-org-details/admin/_admin-layout/resources/organizations': typeof adminOrganizationResourcesPageRouteRoute '/_authenticate/_inject-org-details/admin/_admin-layout/resources/user-identities': typeof adminUserIdentitiesResourcesPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout': typeof projectLayoutRouteWithChildren + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdRouteWithChildren + '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsKmsProjectIdRouteWithChildren + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdRouteWithChildren + '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdRouteWithChildren + '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSshProjectIdRouteWithChildren '/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId/approval': typeof secretManagerRedirectsRedirectApprovalPageRoute '/_authenticate/_inject-org-details/_org-layout/organization/settings/oauth/callback': typeof organizationSettingsPageOauthCallbackPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout': typeof projectLayoutGeneralRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutIntegrationsRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutKmsRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSshRouteWithChildren + '/_authenticate/_inject-org-details/_org-layout/integrations/azure-app-configuration/oauth2/callback': typeof secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectRoute + '/_authenticate/_inject-org-details/_org-layout/integrations/azure-key-vault/oauth2/callback': typeof secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectRoute + '/_authenticate/_inject-org-details/_org-layout/integrations/bitbucket/oauth2/callback': typeof secretManagerIntegrationsRouteBitbucketOauthRedirectRoute + '/_authenticate/_inject-org-details/_org-layout/integrations/gcp-secret-manager/oauth2/callback': typeof secretManagerIntegrationsRouteGcpOauthRedirectRoute + '/_authenticate/_inject-org-details/_org-layout/integrations/github/oauth2/callback': typeof secretManagerIntegrationsRouteGithubOauthRedirectRoute + '/_authenticate/_inject-org-details/_org-layout/integrations/gitlab/oauth2/callback': typeof secretManagerIntegrationsRouteGitlabOauthRedirectRoute + '/_authenticate/_inject-org-details/_org-layout/integrations/heroku/oauth2/callback': typeof secretManagerIntegrationsRouteHerokuOauthRedirectRoute + '/_authenticate/_inject-org-details/_org-layout/integrations/netlify/oauth2/callback': typeof secretManagerIntegrationsRouteNetlifyOauthRedirectRoute + '/_authenticate/_inject-org-details/_org-layout/integrations/vercel/oauth2/callback': typeof secretManagerIntegrationsRouteVercelOauthRedirectRoute + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout': typeof certManagerLayoutRouteWithChildren + '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout': typeof kmsLayoutRouteWithChildren + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout': typeof secretManagerLayoutRouteWithChildren + '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout': typeof secretScanningLayoutRouteWithChildren + '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout': typeof sshLayoutRouteWithChildren '/_authenticate/_inject-org-details/_org-layout/organization/app-connections/$appConnection/oauth/callback': typeof organizationAppConnectionsOauthCallbackPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/access-management': typeof projectAccessControlPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/settings': typeof projectSettingsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout': typeof certManagerLayoutRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout': typeof kmsLayoutRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout': typeof secretManagerLayoutRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout': typeof secretScanningLayoutRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout': typeof sshLayoutRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/groups/$groupId': typeof projectGroupDetailsByIDPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/members/$membershipId': typeof projectMemberDetailsByIDPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/alerting': typeof certManagerAlertingPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificate-authorities': typeof certManagerCertificateAuthoritiesPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificates': typeof certManagerCertificatesPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/settings': typeof certManagerSettingsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout/kmip': typeof kmsKmipPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout/overview': typeof kmsOverviewPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout/settings': typeof kmsSettingsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/allowlist': typeof secretManagerIPAllowlistPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/approval': typeof secretManagerSecretApprovalsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/overview': typeof secretManagerOverviewPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/secret-rotation': typeof secretManagerSecretRotationPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/settings': typeof secretManagerSettingsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/findings': typeof secretScanningSecretScanningFindingsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/settings': typeof secretScanningSettingsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/cas': typeof sshSshCasPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/certificates': typeof sshSshCertsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/overview': typeof sshSshHostsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/settings': typeof sshSettingsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificate-templates': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutCertificateTemplatesRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/subscribers': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutCertManagerCertManagerLayoutSubscribersRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutIntegrationsRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/data-sources': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretScanningSecretScanningLayoutDataSourcesRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificate-templates/': typeof certManagerPkiTemplateListPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/subscribers/': typeof certManagerPkiSubscribersPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/': typeof secretManagerIntegrationsListPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/data-sources/': typeof secretScanningSecretScanningDataSourcesPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/ca/$caName': typeof certManagerCertAuthDetailsByIDPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/subscribers/$subscriberName': typeof certManagerPkiSubscriberDetailsByIDPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/$integrationId': typeof secretManagerIntegrationsDetailsByIDPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/select-integration-auth': typeof secretManagerIntegrationsSelectIntegrationAuthPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/secrets/$envSlug': typeof secretManagerSecretDashboardPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/ca/$caId': typeof sshSshCaByIDPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/ssh-host-groups/$sshHostGroupId': typeof sshSshHostGroupDetailsByIDPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/pki-collections/$collectionId': typeof certManagerPkiCollectionDetailsByIDPageRoutesRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/azure-app-configuration/oauth2/callback': typeof secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/azure-key-vault/oauth2/callback': typeof secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/bitbucket/oauth2/callback': typeof secretManagerIntegrationsRouteBitbucketOauthRedirectRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/gcp-secret-manager/oauth2/callback': typeof secretManagerIntegrationsRouteGcpOauthRedirectRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/github/oauth2/callback': typeof secretManagerIntegrationsRouteGithubOauthRedirectRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/gitlab/oauth2/callback': typeof secretManagerIntegrationsRouteGitlabOauthRedirectRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/heroku/oauth2/callback': typeof secretManagerIntegrationsRouteHerokuOauthRedirectRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/netlify/oauth2/callback': typeof secretManagerIntegrationsRouteNetlifyOauthRedirectRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/vercel/oauth2/callback': typeof secretManagerIntegrationsRouteVercelOauthRedirectRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-parameter-store/authorize': typeof secretManagerIntegrationsAwsParameterStoreAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-parameter-store/create': typeof secretManagerIntegrationsAwsParameterStoreConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-secret-manager/authorize': typeof secretManagerIntegrationsAwsSecretManagerAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-secret-manager/create': typeof secretManagerIntegrationsAwsSecretManagerConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-app-configuration/create': typeof secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-devops/authorize': typeof secretManagerIntegrationsAzureDevopsAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-devops/create': typeof secretManagerIntegrationsAzureDevopsConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-key-vault/authorize': typeof secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-key-vault/create': typeof secretManagerIntegrationsAzureKeyVaultConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/bitbucket/create': typeof secretManagerIntegrationsBitbucketConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/checkly/authorize': typeof secretManagerIntegrationsChecklyAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/checkly/create': typeof secretManagerIntegrationsChecklyConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/circleci/authorize': typeof secretManagerIntegrationsCircleCIAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/circleci/create': typeof secretManagerIntegrationsCircleCIConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloud-66/authorize': typeof secretManagerIntegrationsCloud66AuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloud-66/create': typeof secretManagerIntegrationsCloud66ConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-pages/authorize': typeof secretManagerIntegrationsCloudflarePagesAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-pages/create': typeof secretManagerIntegrationsCloudflarePagesConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-workers/authorize': typeof secretManagerIntegrationsCloudflareWorkersAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-workers/create': typeof secretManagerIntegrationsCloudflareWorkersConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/codefresh/authorize': typeof secretManagerIntegrationsCodefreshAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/codefresh/create': typeof secretManagerIntegrationsCodefreshConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/databricks/authorize': typeof secretManagerIntegrationsDatabricksAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/databricks/create': typeof secretManagerIntegrationsDatabricksConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/digital-ocean-app-platform/authorize': typeof secretManagerIntegrationsDigitalOceanAppPlatformAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/digital-ocean-app-platform/create': typeof secretManagerIntegrationsDigitalOceanAppPlatformConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/flyio/authorize': typeof secretManagerIntegrationsFlyioAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/flyio/create': typeof secretManagerIntegrationsFlyioConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gcp-secret-manager/authorize': typeof secretManagerIntegrationsGcpSecretManagerAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gcp-secret-manager/create': typeof secretManagerIntegrationsGcpSecretManagerConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/github/auth-mode-selection': typeof secretManagerIntegrationsGithubAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/github/create': typeof secretManagerIntegrationsGithubConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gitlab/authorize': typeof secretManagerIntegrationsGitlabAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gitlab/create': typeof secretManagerIntegrationsGitlabConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hashicorp-vault/authorize': typeof secretManagerIntegrationsHashicorpVaultAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hashicorp-vault/create': typeof secretManagerIntegrationsHashicorpVaultConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hasura-cloud/authorize': typeof secretManagerIntegrationsHasuraCloudAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hasura-cloud/create': typeof secretManagerIntegrationsHasuraCloudConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/heroku/create': typeof secretManagerIntegrationsHerokuConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/laravel-forge/authorize': typeof secretManagerIntegrationsLaravelForgeAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/laravel-forge/create': typeof secretManagerIntegrationsLaravelForgeConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/netlify/create': typeof secretManagerIntegrationsNetlifyConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/northflank/authorize': typeof secretManagerIntegrationsNorthflankAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/northflank/create': typeof secretManagerIntegrationsNorthflankConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/octopus-deploy/authorize': typeof secretManagerIntegrationsOctopusDeployAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/octopus-deploy/create': typeof secretManagerIntegrationsOctopusDeployConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/qovery/authorize': typeof secretManagerIntegrationsQoveryAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/qovery/create': typeof secretManagerIntegrationsQoveryConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/railway/authorize': typeof secretManagerIntegrationsRailwayAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/railway/create': typeof secretManagerIntegrationsRailwayConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/render/authorize': typeof secretManagerIntegrationsRenderAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/render/create': typeof secretManagerIntegrationsRenderConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/rundeck/authorize': typeof secretManagerIntegrationsRundeckAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/rundeck/create': typeof secretManagerIntegrationsRundeckConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/supabase/authorize': typeof secretManagerIntegrationsSupabaseAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/supabase/create': typeof secretManagerIntegrationsSupabaseConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/teamcity/authorize': typeof secretManagerIntegrationsTeamcityAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/teamcity/create': typeof secretManagerIntegrationsTeamcityConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/terraform-cloud/authorize': typeof secretManagerIntegrationsTerraformCloudAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/terraform-cloud/create': typeof secretManagerIntegrationsTerraformCloudConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/travisci/authorize': typeof secretManagerIntegrationsTravisCIAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/travisci/create': typeof secretManagerIntegrationsTravisCIConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/vercel/create': typeof secretManagerIntegrationsVercelConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/windmill/authorize': typeof secretManagerIntegrationsWindmillAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/windmill/create': typeof secretManagerIntegrationsWindmillConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/data-sources/$type/$dataSourceId': typeof secretScanningSecretScanningDataSourceByIdPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/': typeof secretManagerCommitsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-app-configuration/oauth2/callback': typeof secretManagerIntegrationsAzureAppConfigurationOauthCallbackPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-key-vault/oauth2/callback': typeof secretManagerIntegrationsAzureKeyVaultOauthCallbackPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/bitbucket/oauth2/callback': typeof secretManagerIntegrationsBitbucketOauthCallbackPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gcp-secret-manager/oauth2/callback': typeof secretManagerIntegrationsGcpSecretManagerOauthCallbackPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/github/oauth2/callback': typeof secretManagerIntegrationsGithubOauthCallbackPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gitlab/oauth2/callback': typeof secretManagerIntegrationsGitlabOauthCallbackPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/heroku/oauth2/callback': typeof secretManagerIntegrationsHerokuOauthCallbackPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/netlify/oauth2/callback': typeof secretManagerIntegrationsNetlifyOauthCallbackPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/secret-syncs/$destination/$syncId': typeof secretManagerSecretSyncDetailsByIDPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/vercel/oauth2/callback': typeof secretManagerIntegrationsVercelOauthCallbackPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/$commitId': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsProjectIdProjectLayoutSecretManagerSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/$commitId/': typeof secretManagerCommitDetailsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/$commitId/restore': typeof secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/alerting': typeof certManagerAlertingPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificate-authorities': typeof certManagerCertificateAuthoritiesPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificates': typeof certManagerCertificatesPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/settings': typeof certManagerSettingsPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/kmip': typeof kmsKmipPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/overview': typeof kmsOverviewPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/settings': typeof kmsSettingsPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/allowlist': typeof secretManagerIPAllowlistPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/approval': typeof secretManagerSecretApprovalsPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/overview': typeof secretManagerOverviewPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/secret-rotation': typeof secretManagerSecretRotationPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/settings': typeof secretManagerSettingsPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/findings': typeof secretScanningSecretScanningFindingsPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/settings': typeof secretScanningSettingsPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/cas': typeof sshSshCasPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/certificates': typeof sshSshCertsPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/overview': typeof sshSshHostsPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/settings': typeof sshSettingsPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/access-management': typeof projectAccessControlPageRouteCertManagerRoute + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesRouteWithChildren + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/subscribers': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsCertManagementProjectIdCertManagerLayoutSubscribersRouteWithChildren + '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/access-management': typeof projectAccessControlPageRouteKmsRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/access-management': typeof projectAccessControlPageRouteSecretManagerRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRouteWithChildren + '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/access-management': typeof projectAccessControlPageRouteSecretScanningRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRouteWithChildren + '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/access-management': typeof projectAccessControlPageRouteSshRoute + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates/': typeof certManagerPkiTemplateListPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/subscribers/': typeof certManagerPkiSubscribersPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/': typeof secretManagerIntegrationsListPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/': typeof secretScanningSecretScanningDataSourcesPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/ca/$caName': typeof certManagerCertAuthDetailsByIDPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/subscribers/$subscriberName': typeof certManagerPkiSubscriberDetailsByIDPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/$integrationId': typeof secretManagerIntegrationsDetailsByIDPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/select-integration-auth': typeof secretManagerIntegrationsSelectIntegrationAuthPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/secrets/$envSlug': typeof secretManagerSecretDashboardPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/ca/$caId': typeof sshSshCaByIDPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/ssh-host-groups/$sshHostGroupId': typeof sshSshHostGroupDetailsByIDPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/groups/$groupId': typeof projectGroupDetailsByIDPageRouteCertManagerRoute + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteCertManagerRoute + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/members/$membershipId': typeof projectMemberDetailsByIDPageRouteCertManagerRoute + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/pki-collections/$collectionId': typeof certManagerPkiCollectionDetailsByIDPageRoutesRoute + '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteCertManagerRoute + '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/groups/$groupId': typeof projectGroupDetailsByIDPageRouteKmsRoute + '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteKmsRoute + '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/members/$membershipId': typeof projectMemberDetailsByIDPageRouteKmsRoute + '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteKmsRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/groups/$groupId': typeof projectGroupDetailsByIDPageRouteSecretManagerRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteSecretManagerRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/members/$membershipId': typeof projectMemberDetailsByIDPageRouteSecretManagerRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteSecretManagerRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/groups/$groupId': typeof projectGroupDetailsByIDPageRouteSecretScanningRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteSecretScanningRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/members/$membershipId': typeof projectMemberDetailsByIDPageRouteSecretScanningRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteSecretScanningRoute + '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/groups/$groupId': typeof projectGroupDetailsByIDPageRouteSshRoute + '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteSshRoute + '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/members/$membershipId': typeof projectMemberDetailsByIDPageRouteSshRoute + '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteSshRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/authorize': typeof secretManagerIntegrationsAwsParameterStoreAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/create': typeof secretManagerIntegrationsAwsParameterStoreConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/authorize': typeof secretManagerIntegrationsAwsSecretManagerAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/create': typeof secretManagerIntegrationsAwsSecretManagerConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/create': typeof secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/authorize': typeof secretManagerIntegrationsAzureDevopsAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/create': typeof secretManagerIntegrationsAzureDevopsConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/authorize': typeof secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/create': typeof secretManagerIntegrationsAzureKeyVaultConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/create': typeof secretManagerIntegrationsBitbucketConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/authorize': typeof secretManagerIntegrationsChecklyAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/create': typeof secretManagerIntegrationsChecklyConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/authorize': typeof secretManagerIntegrationsCircleCIAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/create': typeof secretManagerIntegrationsCircleCIConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/authorize': typeof secretManagerIntegrationsCloud66AuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/create': typeof secretManagerIntegrationsCloud66ConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/authorize': typeof secretManagerIntegrationsCloudflarePagesAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/create': typeof secretManagerIntegrationsCloudflarePagesConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/authorize': typeof secretManagerIntegrationsCloudflareWorkersAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/create': typeof secretManagerIntegrationsCloudflareWorkersConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/authorize': typeof secretManagerIntegrationsCodefreshAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/create': typeof secretManagerIntegrationsCodefreshConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/authorize': typeof secretManagerIntegrationsDatabricksAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/create': typeof secretManagerIntegrationsDatabricksConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/authorize': typeof secretManagerIntegrationsDigitalOceanAppPlatformAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/create': typeof secretManagerIntegrationsDigitalOceanAppPlatformConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/authorize': typeof secretManagerIntegrationsFlyioAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/create': typeof secretManagerIntegrationsFlyioConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/authorize': typeof secretManagerIntegrationsGcpSecretManagerAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/create': typeof secretManagerIntegrationsGcpSecretManagerConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/auth-mode-selection': typeof secretManagerIntegrationsGithubAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/create': typeof secretManagerIntegrationsGithubConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/authorize': typeof secretManagerIntegrationsGitlabAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/create': typeof secretManagerIntegrationsGitlabConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/authorize': typeof secretManagerIntegrationsHashicorpVaultAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/create': typeof secretManagerIntegrationsHashicorpVaultConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/authorize': typeof secretManagerIntegrationsHasuraCloudAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/create': typeof secretManagerIntegrationsHasuraCloudConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/create': typeof secretManagerIntegrationsHerokuConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/authorize': typeof secretManagerIntegrationsLaravelForgeAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/create': typeof secretManagerIntegrationsLaravelForgeConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/create': typeof secretManagerIntegrationsNetlifyConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/authorize': typeof secretManagerIntegrationsNorthflankAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/create': typeof secretManagerIntegrationsNorthflankConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/authorize': typeof secretManagerIntegrationsOctopusDeployAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/create': typeof secretManagerIntegrationsOctopusDeployConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/authorize': typeof secretManagerIntegrationsQoveryAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/create': typeof secretManagerIntegrationsQoveryConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/authorize': typeof secretManagerIntegrationsRailwayAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/create': typeof secretManagerIntegrationsRailwayConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/authorize': typeof secretManagerIntegrationsRenderAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/create': typeof secretManagerIntegrationsRenderConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/authorize': typeof secretManagerIntegrationsRundeckAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/create': typeof secretManagerIntegrationsRundeckConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/authorize': typeof secretManagerIntegrationsSupabaseAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/create': typeof secretManagerIntegrationsSupabaseConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/authorize': typeof secretManagerIntegrationsTeamcityAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/create': typeof secretManagerIntegrationsTeamcityConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/authorize': typeof secretManagerIntegrationsTerraformCloudAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/create': typeof secretManagerIntegrationsTerraformCloudConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/authorize': typeof secretManagerIntegrationsTravisCIAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/create': typeof secretManagerIntegrationsTravisCIConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/create': typeof secretManagerIntegrationsVercelConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/authorize': typeof secretManagerIntegrationsWindmillAuthorizePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/create': typeof secretManagerIntegrationsWindmillConfigurePageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/$type/$dataSourceId': typeof secretScanningSecretScanningDataSourceByIdPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRouteWithChildren + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/': typeof secretManagerCommitsPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/oauth2/callback': typeof secretManagerIntegrationsAzureAppConfigurationOauthCallbackPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/oauth2/callback': typeof secretManagerIntegrationsAzureKeyVaultOauthCallbackPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/oauth2/callback': typeof secretManagerIntegrationsBitbucketOauthCallbackPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/oauth2/callback': typeof secretManagerIntegrationsGcpSecretManagerOauthCallbackPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/oauth2/callback': typeof secretManagerIntegrationsGithubOauthCallbackPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/oauth2/callback': typeof secretManagerIntegrationsGitlabOauthCallbackPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/oauth2/callback': typeof secretManagerIntegrationsHerokuOauthCallbackPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/oauth2/callback': typeof secretManagerIntegrationsNetlifyOauthCallbackPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/secret-syncs/$destination/$syncId': typeof secretManagerSecretSyncDetailsByIDPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/oauth2/callback': typeof secretManagerIntegrationsVercelOauthCallbackPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId': typeof AuthenticateInjectOrgDetailsOrgLayoutProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteWithChildren + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/': typeof secretManagerCommitDetailsPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/restore': typeof secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteRoute } export interface FileRouteTypes { @@ -4923,6 +5229,7 @@ export interface FileRouteTypes { | '/personal-settings/' | '/login/provider/error' | '/login/provider/success' + | '/integrations' | '/organization' | '/admin/' | '/organization/access-management' @@ -4939,7 +5246,6 @@ export interface FileRouteTypes { | '/organization/gateways' | '/organization/secret-sharing' | '/organization/settings' - | '/projects/$projectId' | '/secret-manager/$projectId' | '/organization/app-connections/' | '/organization/gateways/' @@ -4953,145 +5259,163 @@ export interface FileRouteTypes { | '/admin/resources/machine-identities' | '/admin/resources/organizations' | '/admin/resources/user-identities' + | '/projects/cert-management/$projectId' + | '/projects/kms/$projectId' + | '/projects/secret-management/$projectId' + | '/projects/secret-scanning/$projectId' + | '/projects/ssh/$projectId' | '/secret-manager/$projectId/approval' | '/organization/settings/oauth/callback' - | '/projects/$projectId/cert-manager' - | '/projects/$projectId/integrations' - | '/projects/$projectId/kms' - | '/projects/$projectId/secret-manager' - | '/projects/$projectId/secret-scanning' - | '/projects/$projectId/ssh' + | '/integrations/azure-app-configuration/oauth2/callback' + | '/integrations/azure-key-vault/oauth2/callback' + | '/integrations/bitbucket/oauth2/callback' + | '/integrations/gcp-secret-manager/oauth2/callback' + | '/integrations/github/oauth2/callback' + | '/integrations/gitlab/oauth2/callback' + | '/integrations/heroku/oauth2/callback' + | '/integrations/netlify/oauth2/callback' + | '/integrations/vercel/oauth2/callback' | '/organization/app-connections/$appConnection/oauth/callback' - | '/projects/$projectId/access-management' - | '/projects/$projectId/settings' - | '/projects/$projectId/groups/$groupId' - | '/projects/$projectId/identities/$identityId' - | '/projects/$projectId/members/$membershipId' - | '/projects/$projectId/roles/$roleSlug' - | '/projects/$projectId/cert-manager/alerting' - | '/projects/$projectId/cert-manager/certificate-authorities' - | '/projects/$projectId/cert-manager/certificates' - | '/projects/$projectId/cert-manager/settings' - | '/projects/$projectId/kms/kmip' - | '/projects/$projectId/kms/overview' - | '/projects/$projectId/kms/settings' - | '/projects/$projectId/secret-manager/allowlist' - | '/projects/$projectId/secret-manager/approval' - | '/projects/$projectId/secret-manager/overview' - | '/projects/$projectId/secret-manager/secret-rotation' - | '/projects/$projectId/secret-manager/settings' - | '/projects/$projectId/secret-scanning/findings' - | '/projects/$projectId/secret-scanning/settings' - | '/projects/$projectId/ssh/cas' - | '/projects/$projectId/ssh/certificates' - | '/projects/$projectId/ssh/overview' - | '/projects/$projectId/ssh/settings' - | '/projects/$projectId/cert-manager/certificate-templates' - | '/projects/$projectId/cert-manager/subscribers' - | '/projects/$projectId/secret-manager/integrations' - | '/projects/$projectId/secret-scanning/data-sources' - | '/projects/$projectId/cert-manager/certificate-templates/' - | '/projects/$projectId/cert-manager/subscribers/' - | '/projects/$projectId/secret-manager/integrations/' - | '/projects/$projectId/secret-scanning/data-sources/' - | '/projects/$projectId/cert-manager/ca/$caName' - | '/projects/$projectId/cert-manager/subscribers/$subscriberName' - | '/projects/$projectId/secret-manager/integrations/$integrationId' - | '/projects/$projectId/secret-manager/integrations/select-integration-auth' - | '/projects/$projectId/secret-manager/secrets/$envSlug' - | '/projects/$projectId/ssh/ca/$caId' - | '/projects/$projectId/ssh/ssh-host-groups/$sshHostGroupId' - | '/projects/$projectId/cert-manager/pki-collections/$collectionId' - | '/projects/$projectId/integrations/azure-app-configuration/oauth2/callback' - | '/projects/$projectId/integrations/azure-key-vault/oauth2/callback' - | '/projects/$projectId/integrations/bitbucket/oauth2/callback' - | '/projects/$projectId/integrations/gcp-secret-manager/oauth2/callback' - | '/projects/$projectId/integrations/github/oauth2/callback' - | '/projects/$projectId/integrations/gitlab/oauth2/callback' - | '/projects/$projectId/integrations/heroku/oauth2/callback' - | '/projects/$projectId/integrations/netlify/oauth2/callback' - | '/projects/$projectId/integrations/vercel/oauth2/callback' - | '/projects/$projectId/secret-manager/integrations/aws-parameter-store/authorize' - | '/projects/$projectId/secret-manager/integrations/aws-parameter-store/create' - | '/projects/$projectId/secret-manager/integrations/aws-secret-manager/authorize' - | '/projects/$projectId/secret-manager/integrations/aws-secret-manager/create' - | '/projects/$projectId/secret-manager/integrations/azure-app-configuration/create' - | '/projects/$projectId/secret-manager/integrations/azure-devops/authorize' - | '/projects/$projectId/secret-manager/integrations/azure-devops/create' - | '/projects/$projectId/secret-manager/integrations/azure-key-vault/authorize' - | '/projects/$projectId/secret-manager/integrations/azure-key-vault/create' - | '/projects/$projectId/secret-manager/integrations/bitbucket/create' - | '/projects/$projectId/secret-manager/integrations/checkly/authorize' - | '/projects/$projectId/secret-manager/integrations/checkly/create' - | '/projects/$projectId/secret-manager/integrations/circleci/authorize' - | '/projects/$projectId/secret-manager/integrations/circleci/create' - | '/projects/$projectId/secret-manager/integrations/cloud-66/authorize' - | '/projects/$projectId/secret-manager/integrations/cloud-66/create' - | '/projects/$projectId/secret-manager/integrations/cloudflare-pages/authorize' - | '/projects/$projectId/secret-manager/integrations/cloudflare-pages/create' - | '/projects/$projectId/secret-manager/integrations/cloudflare-workers/authorize' - | '/projects/$projectId/secret-manager/integrations/cloudflare-workers/create' - | '/projects/$projectId/secret-manager/integrations/codefresh/authorize' - | '/projects/$projectId/secret-manager/integrations/codefresh/create' - | '/projects/$projectId/secret-manager/integrations/databricks/authorize' - | '/projects/$projectId/secret-manager/integrations/databricks/create' - | '/projects/$projectId/secret-manager/integrations/digital-ocean-app-platform/authorize' - | '/projects/$projectId/secret-manager/integrations/digital-ocean-app-platform/create' - | '/projects/$projectId/secret-manager/integrations/flyio/authorize' - | '/projects/$projectId/secret-manager/integrations/flyio/create' - | '/projects/$projectId/secret-manager/integrations/gcp-secret-manager/authorize' - | '/projects/$projectId/secret-manager/integrations/gcp-secret-manager/create' - | '/projects/$projectId/secret-manager/integrations/github/auth-mode-selection' - | '/projects/$projectId/secret-manager/integrations/github/create' - | '/projects/$projectId/secret-manager/integrations/gitlab/authorize' - | '/projects/$projectId/secret-manager/integrations/gitlab/create' - | '/projects/$projectId/secret-manager/integrations/hashicorp-vault/authorize' - | '/projects/$projectId/secret-manager/integrations/hashicorp-vault/create' - | '/projects/$projectId/secret-manager/integrations/hasura-cloud/authorize' - | '/projects/$projectId/secret-manager/integrations/hasura-cloud/create' - | '/projects/$projectId/secret-manager/integrations/heroku/create' - | '/projects/$projectId/secret-manager/integrations/laravel-forge/authorize' - | '/projects/$projectId/secret-manager/integrations/laravel-forge/create' - | '/projects/$projectId/secret-manager/integrations/netlify/create' - | '/projects/$projectId/secret-manager/integrations/northflank/authorize' - | '/projects/$projectId/secret-manager/integrations/northflank/create' - | '/projects/$projectId/secret-manager/integrations/octopus-deploy/authorize' - | '/projects/$projectId/secret-manager/integrations/octopus-deploy/create' - | '/projects/$projectId/secret-manager/integrations/qovery/authorize' - | '/projects/$projectId/secret-manager/integrations/qovery/create' - | '/projects/$projectId/secret-manager/integrations/railway/authorize' - | '/projects/$projectId/secret-manager/integrations/railway/create' - | '/projects/$projectId/secret-manager/integrations/render/authorize' - | '/projects/$projectId/secret-manager/integrations/render/create' - | '/projects/$projectId/secret-manager/integrations/rundeck/authorize' - | '/projects/$projectId/secret-manager/integrations/rundeck/create' - | '/projects/$projectId/secret-manager/integrations/supabase/authorize' - | '/projects/$projectId/secret-manager/integrations/supabase/create' - | '/projects/$projectId/secret-manager/integrations/teamcity/authorize' - | '/projects/$projectId/secret-manager/integrations/teamcity/create' - | '/projects/$projectId/secret-manager/integrations/terraform-cloud/authorize' - | '/projects/$projectId/secret-manager/integrations/terraform-cloud/create' - | '/projects/$projectId/secret-manager/integrations/travisci/authorize' - | '/projects/$projectId/secret-manager/integrations/travisci/create' - | '/projects/$projectId/secret-manager/integrations/vercel/create' - | '/projects/$projectId/secret-manager/integrations/windmill/authorize' - | '/projects/$projectId/secret-manager/integrations/windmill/create' - | '/projects/$projectId/secret-scanning/data-sources/$type/$dataSourceId' - | '/projects/$projectId/secret-manager/commits/$environment/$folderId' - | '/projects/$projectId/secret-manager/commits/$environment/$folderId/' - | '/projects/$projectId/secret-manager/integrations/azure-app-configuration/oauth2/callback' - | '/projects/$projectId/secret-manager/integrations/azure-key-vault/oauth2/callback' - | '/projects/$projectId/secret-manager/integrations/bitbucket/oauth2/callback' - | '/projects/$projectId/secret-manager/integrations/gcp-secret-manager/oauth2/callback' - | '/projects/$projectId/secret-manager/integrations/github/oauth2/callback' - | '/projects/$projectId/secret-manager/integrations/gitlab/oauth2/callback' - | '/projects/$projectId/secret-manager/integrations/heroku/oauth2/callback' - | '/projects/$projectId/secret-manager/integrations/netlify/oauth2/callback' - | '/projects/$projectId/secret-manager/integrations/secret-syncs/$destination/$syncId' - | '/projects/$projectId/secret-manager/integrations/vercel/oauth2/callback' - | '/projects/$projectId/secret-manager/commits/$environment/$folderId/$commitId' - | '/projects/$projectId/secret-manager/commits/$environment/$folderId/$commitId/' - | '/projects/$projectId/secret-manager/commits/$environment/$folderId/$commitId/restore' + | '/projects/cert-management/$projectId/alerting' + | '/projects/cert-management/$projectId/certificate-authorities' + | '/projects/cert-management/$projectId/certificates' + | '/projects/cert-management/$projectId/settings' + | '/projects/kms/$projectId/kmip' + | '/projects/kms/$projectId/overview' + | '/projects/kms/$projectId/settings' + | '/projects/secret-management/$projectId/allowlist' + | '/projects/secret-management/$projectId/approval' + | '/projects/secret-management/$projectId/overview' + | '/projects/secret-management/$projectId/secret-rotation' + | '/projects/secret-management/$projectId/settings' + | '/projects/secret-scanning/$projectId/findings' + | '/projects/secret-scanning/$projectId/settings' + | '/projects/ssh/$projectId/cas' + | '/projects/ssh/$projectId/certificates' + | '/projects/ssh/$projectId/overview' + | '/projects/ssh/$projectId/settings' + | '/projects/cert-management/$projectId/access-management' + | '/projects/cert-management/$projectId/certificate-templates' + | '/projects/cert-management/$projectId/subscribers' + | '/projects/kms/$projectId/access-management' + | '/projects/secret-management/$projectId/access-management' + | '/projects/secret-management/$projectId/integrations' + | '/projects/secret-scanning/$projectId/access-management' + | '/projects/secret-scanning/$projectId/data-sources' + | '/projects/ssh/$projectId/access-management' + | '/projects/cert-management/$projectId/certificate-templates/' + | '/projects/cert-management/$projectId/subscribers/' + | '/projects/secret-management/$projectId/integrations/' + | '/projects/secret-scanning/$projectId/data-sources/' + | '/projects/cert-management/$projectId/ca/$caName' + | '/projects/cert-management/$projectId/subscribers/$subscriberName' + | '/projects/secret-management/$projectId/integrations/$integrationId' + | '/projects/secret-management/$projectId/integrations/select-integration-auth' + | '/projects/secret-management/$projectId/secrets/$envSlug' + | '/projects/ssh/$projectId/ca/$caId' + | '/projects/ssh/$projectId/ssh-host-groups/$sshHostGroupId' + | '/projects/cert-management/$projectId/groups/$groupId' + | '/projects/cert-management/$projectId/identities/$identityId' + | '/projects/cert-management/$projectId/members/$membershipId' + | '/projects/cert-management/$projectId/pki-collections/$collectionId' + | '/projects/cert-management/$projectId/roles/$roleSlug' + | '/projects/kms/$projectId/groups/$groupId' + | '/projects/kms/$projectId/identities/$identityId' + | '/projects/kms/$projectId/members/$membershipId' + | '/projects/kms/$projectId/roles/$roleSlug' + | '/projects/secret-management/$projectId/groups/$groupId' + | '/projects/secret-management/$projectId/identities/$identityId' + | '/projects/secret-management/$projectId/members/$membershipId' + | '/projects/secret-management/$projectId/roles/$roleSlug' + | '/projects/secret-scanning/$projectId/groups/$groupId' + | '/projects/secret-scanning/$projectId/identities/$identityId' + | '/projects/secret-scanning/$projectId/members/$membershipId' + | '/projects/secret-scanning/$projectId/roles/$roleSlug' + | '/projects/ssh/$projectId/groups/$groupId' + | '/projects/ssh/$projectId/identities/$identityId' + | '/projects/ssh/$projectId/members/$membershipId' + | '/projects/ssh/$projectId/roles/$roleSlug' + | '/projects/secret-management/$projectId/integrations/aws-parameter-store/authorize' + | '/projects/secret-management/$projectId/integrations/aws-parameter-store/create' + | '/projects/secret-management/$projectId/integrations/aws-secret-manager/authorize' + | '/projects/secret-management/$projectId/integrations/aws-secret-manager/create' + | '/projects/secret-management/$projectId/integrations/azure-app-configuration/create' + | '/projects/secret-management/$projectId/integrations/azure-devops/authorize' + | '/projects/secret-management/$projectId/integrations/azure-devops/create' + | '/projects/secret-management/$projectId/integrations/azure-key-vault/authorize' + | '/projects/secret-management/$projectId/integrations/azure-key-vault/create' + | '/projects/secret-management/$projectId/integrations/bitbucket/create' + | '/projects/secret-management/$projectId/integrations/checkly/authorize' + | '/projects/secret-management/$projectId/integrations/checkly/create' + | '/projects/secret-management/$projectId/integrations/circleci/authorize' + | '/projects/secret-management/$projectId/integrations/circleci/create' + | '/projects/secret-management/$projectId/integrations/cloud-66/authorize' + | '/projects/secret-management/$projectId/integrations/cloud-66/create' + | '/projects/secret-management/$projectId/integrations/cloudflare-pages/authorize' + | '/projects/secret-management/$projectId/integrations/cloudflare-pages/create' + | '/projects/secret-management/$projectId/integrations/cloudflare-workers/authorize' + | '/projects/secret-management/$projectId/integrations/cloudflare-workers/create' + | '/projects/secret-management/$projectId/integrations/codefresh/authorize' + | '/projects/secret-management/$projectId/integrations/codefresh/create' + | '/projects/secret-management/$projectId/integrations/databricks/authorize' + | '/projects/secret-management/$projectId/integrations/databricks/create' + | '/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/authorize' + | '/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/create' + | '/projects/secret-management/$projectId/integrations/flyio/authorize' + | '/projects/secret-management/$projectId/integrations/flyio/create' + | '/projects/secret-management/$projectId/integrations/gcp-secret-manager/authorize' + | '/projects/secret-management/$projectId/integrations/gcp-secret-manager/create' + | '/projects/secret-management/$projectId/integrations/github/auth-mode-selection' + | '/projects/secret-management/$projectId/integrations/github/create' + | '/projects/secret-management/$projectId/integrations/gitlab/authorize' + | '/projects/secret-management/$projectId/integrations/gitlab/create' + | '/projects/secret-management/$projectId/integrations/hashicorp-vault/authorize' + | '/projects/secret-management/$projectId/integrations/hashicorp-vault/create' + | '/projects/secret-management/$projectId/integrations/hasura-cloud/authorize' + | '/projects/secret-management/$projectId/integrations/hasura-cloud/create' + | '/projects/secret-management/$projectId/integrations/heroku/create' + | '/projects/secret-management/$projectId/integrations/laravel-forge/authorize' + | '/projects/secret-management/$projectId/integrations/laravel-forge/create' + | '/projects/secret-management/$projectId/integrations/netlify/create' + | '/projects/secret-management/$projectId/integrations/northflank/authorize' + | '/projects/secret-management/$projectId/integrations/northflank/create' + | '/projects/secret-management/$projectId/integrations/octopus-deploy/authorize' + | '/projects/secret-management/$projectId/integrations/octopus-deploy/create' + | '/projects/secret-management/$projectId/integrations/qovery/authorize' + | '/projects/secret-management/$projectId/integrations/qovery/create' + | '/projects/secret-management/$projectId/integrations/railway/authorize' + | '/projects/secret-management/$projectId/integrations/railway/create' + | '/projects/secret-management/$projectId/integrations/render/authorize' + | '/projects/secret-management/$projectId/integrations/render/create' + | '/projects/secret-management/$projectId/integrations/rundeck/authorize' + | '/projects/secret-management/$projectId/integrations/rundeck/create' + | '/projects/secret-management/$projectId/integrations/supabase/authorize' + | '/projects/secret-management/$projectId/integrations/supabase/create' + | '/projects/secret-management/$projectId/integrations/teamcity/authorize' + | '/projects/secret-management/$projectId/integrations/teamcity/create' + | '/projects/secret-management/$projectId/integrations/terraform-cloud/authorize' + | '/projects/secret-management/$projectId/integrations/terraform-cloud/create' + | '/projects/secret-management/$projectId/integrations/travisci/authorize' + | '/projects/secret-management/$projectId/integrations/travisci/create' + | '/projects/secret-management/$projectId/integrations/vercel/create' + | '/projects/secret-management/$projectId/integrations/windmill/authorize' + | '/projects/secret-management/$projectId/integrations/windmill/create' + | '/projects/secret-scanning/$projectId/data-sources/$type/$dataSourceId' + | '/projects/secret-management/$projectId/commits/$environment/$folderId' + | '/projects/secret-management/$projectId/commits/$environment/$folderId/' + | '/projects/secret-management/$projectId/integrations/azure-app-configuration/oauth2/callback' + | '/projects/secret-management/$projectId/integrations/azure-key-vault/oauth2/callback' + | '/projects/secret-management/$projectId/integrations/bitbucket/oauth2/callback' + | '/projects/secret-management/$projectId/integrations/gcp-secret-manager/oauth2/callback' + | '/projects/secret-management/$projectId/integrations/github/oauth2/callback' + | '/projects/secret-management/$projectId/integrations/gitlab/oauth2/callback' + | '/projects/secret-management/$projectId/integrations/heroku/oauth2/callback' + | '/projects/secret-management/$projectId/integrations/netlify/oauth2/callback' + | '/projects/secret-management/$projectId/integrations/secret-syncs/$destination/$syncId' + | '/projects/secret-management/$projectId/integrations/vercel/oauth2/callback' + | '/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId' + | '/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId/' + | '/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId/restore' fileRoutesByTo: FileRoutesByTo to: | '/' @@ -5119,6 +5443,7 @@ export interface FileRouteTypes { | '/admin' | '/login/provider/error' | '/login/provider/success' + | '/integrations' | '/organization' | '/organization/access-management' | '/organization/admin' @@ -5130,7 +5455,6 @@ export interface FileRouteTypes { | '/admin/encryption' | '/admin/environment' | '/admin/integrations' - | '/projects/$projectId' | '/secret-manager/$projectId' | '/organization/app-connections' | '/organization/gateways' @@ -5144,139 +5468,157 @@ export interface FileRouteTypes { | '/admin/resources/machine-identities' | '/admin/resources/organizations' | '/admin/resources/user-identities' + | '/projects/cert-management/$projectId' + | '/projects/kms/$projectId' + | '/projects/secret-management/$projectId' + | '/projects/secret-scanning/$projectId' + | '/projects/ssh/$projectId' | '/secret-manager/$projectId/approval' | '/organization/settings/oauth/callback' - | '/projects/$projectId/cert-manager' - | '/projects/$projectId/integrations' - | '/projects/$projectId/kms' - | '/projects/$projectId/secret-manager' - | '/projects/$projectId/secret-scanning' - | '/projects/$projectId/ssh' + | '/integrations/azure-app-configuration/oauth2/callback' + | '/integrations/azure-key-vault/oauth2/callback' + | '/integrations/bitbucket/oauth2/callback' + | '/integrations/gcp-secret-manager/oauth2/callback' + | '/integrations/github/oauth2/callback' + | '/integrations/gitlab/oauth2/callback' + | '/integrations/heroku/oauth2/callback' + | '/integrations/netlify/oauth2/callback' + | '/integrations/vercel/oauth2/callback' | '/organization/app-connections/$appConnection/oauth/callback' - | '/projects/$projectId/access-management' - | '/projects/$projectId/settings' - | '/projects/$projectId/groups/$groupId' - | '/projects/$projectId/identities/$identityId' - | '/projects/$projectId/members/$membershipId' - | '/projects/$projectId/roles/$roleSlug' - | '/projects/$projectId/cert-manager/alerting' - | '/projects/$projectId/cert-manager/certificate-authorities' - | '/projects/$projectId/cert-manager/certificates' - | '/projects/$projectId/cert-manager/settings' - | '/projects/$projectId/kms/kmip' - | '/projects/$projectId/kms/overview' - | '/projects/$projectId/kms/settings' - | '/projects/$projectId/secret-manager/allowlist' - | '/projects/$projectId/secret-manager/approval' - | '/projects/$projectId/secret-manager/overview' - | '/projects/$projectId/secret-manager/secret-rotation' - | '/projects/$projectId/secret-manager/settings' - | '/projects/$projectId/secret-scanning/findings' - | '/projects/$projectId/secret-scanning/settings' - | '/projects/$projectId/ssh/cas' - | '/projects/$projectId/ssh/certificates' - | '/projects/$projectId/ssh/overview' - | '/projects/$projectId/ssh/settings' - | '/projects/$projectId/cert-manager/certificate-templates' - | '/projects/$projectId/cert-manager/subscribers' - | '/projects/$projectId/secret-manager/integrations' - | '/projects/$projectId/secret-scanning/data-sources' - | '/projects/$projectId/cert-manager/ca/$caName' - | '/projects/$projectId/cert-manager/subscribers/$subscriberName' - | '/projects/$projectId/secret-manager/integrations/$integrationId' - | '/projects/$projectId/secret-manager/integrations/select-integration-auth' - | '/projects/$projectId/secret-manager/secrets/$envSlug' - | '/projects/$projectId/ssh/ca/$caId' - | '/projects/$projectId/ssh/ssh-host-groups/$sshHostGroupId' - | '/projects/$projectId/cert-manager/pki-collections/$collectionId' - | '/projects/$projectId/integrations/azure-app-configuration/oauth2/callback' - | '/projects/$projectId/integrations/azure-key-vault/oauth2/callback' - | '/projects/$projectId/integrations/bitbucket/oauth2/callback' - | '/projects/$projectId/integrations/gcp-secret-manager/oauth2/callback' - | '/projects/$projectId/integrations/github/oauth2/callback' - | '/projects/$projectId/integrations/gitlab/oauth2/callback' - | '/projects/$projectId/integrations/heroku/oauth2/callback' - | '/projects/$projectId/integrations/netlify/oauth2/callback' - | '/projects/$projectId/integrations/vercel/oauth2/callback' - | '/projects/$projectId/secret-manager/integrations/aws-parameter-store/authorize' - | '/projects/$projectId/secret-manager/integrations/aws-parameter-store/create' - | '/projects/$projectId/secret-manager/integrations/aws-secret-manager/authorize' - | '/projects/$projectId/secret-manager/integrations/aws-secret-manager/create' - | '/projects/$projectId/secret-manager/integrations/azure-app-configuration/create' - | '/projects/$projectId/secret-manager/integrations/azure-devops/authorize' - | '/projects/$projectId/secret-manager/integrations/azure-devops/create' - | '/projects/$projectId/secret-manager/integrations/azure-key-vault/authorize' - | '/projects/$projectId/secret-manager/integrations/azure-key-vault/create' - | '/projects/$projectId/secret-manager/integrations/bitbucket/create' - | '/projects/$projectId/secret-manager/integrations/checkly/authorize' - | '/projects/$projectId/secret-manager/integrations/checkly/create' - | '/projects/$projectId/secret-manager/integrations/circleci/authorize' - | '/projects/$projectId/secret-manager/integrations/circleci/create' - | '/projects/$projectId/secret-manager/integrations/cloud-66/authorize' - | '/projects/$projectId/secret-manager/integrations/cloud-66/create' - | '/projects/$projectId/secret-manager/integrations/cloudflare-pages/authorize' - | '/projects/$projectId/secret-manager/integrations/cloudflare-pages/create' - | '/projects/$projectId/secret-manager/integrations/cloudflare-workers/authorize' - | '/projects/$projectId/secret-manager/integrations/cloudflare-workers/create' - | '/projects/$projectId/secret-manager/integrations/codefresh/authorize' - | '/projects/$projectId/secret-manager/integrations/codefresh/create' - | '/projects/$projectId/secret-manager/integrations/databricks/authorize' - | '/projects/$projectId/secret-manager/integrations/databricks/create' - | '/projects/$projectId/secret-manager/integrations/digital-ocean-app-platform/authorize' - | '/projects/$projectId/secret-manager/integrations/digital-ocean-app-platform/create' - | '/projects/$projectId/secret-manager/integrations/flyio/authorize' - | '/projects/$projectId/secret-manager/integrations/flyio/create' - | '/projects/$projectId/secret-manager/integrations/gcp-secret-manager/authorize' - | '/projects/$projectId/secret-manager/integrations/gcp-secret-manager/create' - | '/projects/$projectId/secret-manager/integrations/github/auth-mode-selection' - | '/projects/$projectId/secret-manager/integrations/github/create' - | '/projects/$projectId/secret-manager/integrations/gitlab/authorize' - | '/projects/$projectId/secret-manager/integrations/gitlab/create' - | '/projects/$projectId/secret-manager/integrations/hashicorp-vault/authorize' - | '/projects/$projectId/secret-manager/integrations/hashicorp-vault/create' - | '/projects/$projectId/secret-manager/integrations/hasura-cloud/authorize' - | '/projects/$projectId/secret-manager/integrations/hasura-cloud/create' - | '/projects/$projectId/secret-manager/integrations/heroku/create' - | '/projects/$projectId/secret-manager/integrations/laravel-forge/authorize' - | '/projects/$projectId/secret-manager/integrations/laravel-forge/create' - | '/projects/$projectId/secret-manager/integrations/netlify/create' - | '/projects/$projectId/secret-manager/integrations/northflank/authorize' - | '/projects/$projectId/secret-manager/integrations/northflank/create' - | '/projects/$projectId/secret-manager/integrations/octopus-deploy/authorize' - | '/projects/$projectId/secret-manager/integrations/octopus-deploy/create' - | '/projects/$projectId/secret-manager/integrations/qovery/authorize' - | '/projects/$projectId/secret-manager/integrations/qovery/create' - | '/projects/$projectId/secret-manager/integrations/railway/authorize' - | '/projects/$projectId/secret-manager/integrations/railway/create' - | '/projects/$projectId/secret-manager/integrations/render/authorize' - | '/projects/$projectId/secret-manager/integrations/render/create' - | '/projects/$projectId/secret-manager/integrations/rundeck/authorize' - | '/projects/$projectId/secret-manager/integrations/rundeck/create' - | '/projects/$projectId/secret-manager/integrations/supabase/authorize' - | '/projects/$projectId/secret-manager/integrations/supabase/create' - | '/projects/$projectId/secret-manager/integrations/teamcity/authorize' - | '/projects/$projectId/secret-manager/integrations/teamcity/create' - | '/projects/$projectId/secret-manager/integrations/terraform-cloud/authorize' - | '/projects/$projectId/secret-manager/integrations/terraform-cloud/create' - | '/projects/$projectId/secret-manager/integrations/travisci/authorize' - | '/projects/$projectId/secret-manager/integrations/travisci/create' - | '/projects/$projectId/secret-manager/integrations/vercel/create' - | '/projects/$projectId/secret-manager/integrations/windmill/authorize' - | '/projects/$projectId/secret-manager/integrations/windmill/create' - | '/projects/$projectId/secret-scanning/data-sources/$type/$dataSourceId' - | '/projects/$projectId/secret-manager/commits/$environment/$folderId' - | '/projects/$projectId/secret-manager/integrations/azure-app-configuration/oauth2/callback' - | '/projects/$projectId/secret-manager/integrations/azure-key-vault/oauth2/callback' - | '/projects/$projectId/secret-manager/integrations/bitbucket/oauth2/callback' - | '/projects/$projectId/secret-manager/integrations/gcp-secret-manager/oauth2/callback' - | '/projects/$projectId/secret-manager/integrations/github/oauth2/callback' - | '/projects/$projectId/secret-manager/integrations/gitlab/oauth2/callback' - | '/projects/$projectId/secret-manager/integrations/heroku/oauth2/callback' - | '/projects/$projectId/secret-manager/integrations/netlify/oauth2/callback' - | '/projects/$projectId/secret-manager/integrations/secret-syncs/$destination/$syncId' - | '/projects/$projectId/secret-manager/integrations/vercel/oauth2/callback' - | '/projects/$projectId/secret-manager/commits/$environment/$folderId/$commitId' - | '/projects/$projectId/secret-manager/commits/$environment/$folderId/$commitId/restore' + | '/projects/cert-management/$projectId/alerting' + | '/projects/cert-management/$projectId/certificate-authorities' + | '/projects/cert-management/$projectId/certificates' + | '/projects/cert-management/$projectId/settings' + | '/projects/kms/$projectId/kmip' + | '/projects/kms/$projectId/overview' + | '/projects/kms/$projectId/settings' + | '/projects/secret-management/$projectId/allowlist' + | '/projects/secret-management/$projectId/approval' + | '/projects/secret-management/$projectId/overview' + | '/projects/secret-management/$projectId/secret-rotation' + | '/projects/secret-management/$projectId/settings' + | '/projects/secret-scanning/$projectId/findings' + | '/projects/secret-scanning/$projectId/settings' + | '/projects/ssh/$projectId/cas' + | '/projects/ssh/$projectId/certificates' + | '/projects/ssh/$projectId/overview' + | '/projects/ssh/$projectId/settings' + | '/projects/cert-management/$projectId/access-management' + | '/projects/kms/$projectId/access-management' + | '/projects/secret-management/$projectId/access-management' + | '/projects/secret-scanning/$projectId/access-management' + | '/projects/ssh/$projectId/access-management' + | '/projects/cert-management/$projectId/certificate-templates' + | '/projects/cert-management/$projectId/subscribers' + | '/projects/secret-management/$projectId/integrations' + | '/projects/secret-scanning/$projectId/data-sources' + | '/projects/cert-management/$projectId/ca/$caName' + | '/projects/cert-management/$projectId/subscribers/$subscriberName' + | '/projects/secret-management/$projectId/integrations/$integrationId' + | '/projects/secret-management/$projectId/integrations/select-integration-auth' + | '/projects/secret-management/$projectId/secrets/$envSlug' + | '/projects/ssh/$projectId/ca/$caId' + | '/projects/ssh/$projectId/ssh-host-groups/$sshHostGroupId' + | '/projects/cert-management/$projectId/groups/$groupId' + | '/projects/cert-management/$projectId/identities/$identityId' + | '/projects/cert-management/$projectId/members/$membershipId' + | '/projects/cert-management/$projectId/pki-collections/$collectionId' + | '/projects/cert-management/$projectId/roles/$roleSlug' + | '/projects/kms/$projectId/groups/$groupId' + | '/projects/kms/$projectId/identities/$identityId' + | '/projects/kms/$projectId/members/$membershipId' + | '/projects/kms/$projectId/roles/$roleSlug' + | '/projects/secret-management/$projectId/groups/$groupId' + | '/projects/secret-management/$projectId/identities/$identityId' + | '/projects/secret-management/$projectId/members/$membershipId' + | '/projects/secret-management/$projectId/roles/$roleSlug' + | '/projects/secret-scanning/$projectId/groups/$groupId' + | '/projects/secret-scanning/$projectId/identities/$identityId' + | '/projects/secret-scanning/$projectId/members/$membershipId' + | '/projects/secret-scanning/$projectId/roles/$roleSlug' + | '/projects/ssh/$projectId/groups/$groupId' + | '/projects/ssh/$projectId/identities/$identityId' + | '/projects/ssh/$projectId/members/$membershipId' + | '/projects/ssh/$projectId/roles/$roleSlug' + | '/projects/secret-management/$projectId/integrations/aws-parameter-store/authorize' + | '/projects/secret-management/$projectId/integrations/aws-parameter-store/create' + | '/projects/secret-management/$projectId/integrations/aws-secret-manager/authorize' + | '/projects/secret-management/$projectId/integrations/aws-secret-manager/create' + | '/projects/secret-management/$projectId/integrations/azure-app-configuration/create' + | '/projects/secret-management/$projectId/integrations/azure-devops/authorize' + | '/projects/secret-management/$projectId/integrations/azure-devops/create' + | '/projects/secret-management/$projectId/integrations/azure-key-vault/authorize' + | '/projects/secret-management/$projectId/integrations/azure-key-vault/create' + | '/projects/secret-management/$projectId/integrations/bitbucket/create' + | '/projects/secret-management/$projectId/integrations/checkly/authorize' + | '/projects/secret-management/$projectId/integrations/checkly/create' + | '/projects/secret-management/$projectId/integrations/circleci/authorize' + | '/projects/secret-management/$projectId/integrations/circleci/create' + | '/projects/secret-management/$projectId/integrations/cloud-66/authorize' + | '/projects/secret-management/$projectId/integrations/cloud-66/create' + | '/projects/secret-management/$projectId/integrations/cloudflare-pages/authorize' + | '/projects/secret-management/$projectId/integrations/cloudflare-pages/create' + | '/projects/secret-management/$projectId/integrations/cloudflare-workers/authorize' + | '/projects/secret-management/$projectId/integrations/cloudflare-workers/create' + | '/projects/secret-management/$projectId/integrations/codefresh/authorize' + | '/projects/secret-management/$projectId/integrations/codefresh/create' + | '/projects/secret-management/$projectId/integrations/databricks/authorize' + | '/projects/secret-management/$projectId/integrations/databricks/create' + | '/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/authorize' + | '/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/create' + | '/projects/secret-management/$projectId/integrations/flyio/authorize' + | '/projects/secret-management/$projectId/integrations/flyio/create' + | '/projects/secret-management/$projectId/integrations/gcp-secret-manager/authorize' + | '/projects/secret-management/$projectId/integrations/gcp-secret-manager/create' + | '/projects/secret-management/$projectId/integrations/github/auth-mode-selection' + | '/projects/secret-management/$projectId/integrations/github/create' + | '/projects/secret-management/$projectId/integrations/gitlab/authorize' + | '/projects/secret-management/$projectId/integrations/gitlab/create' + | '/projects/secret-management/$projectId/integrations/hashicorp-vault/authorize' + | '/projects/secret-management/$projectId/integrations/hashicorp-vault/create' + | '/projects/secret-management/$projectId/integrations/hasura-cloud/authorize' + | '/projects/secret-management/$projectId/integrations/hasura-cloud/create' + | '/projects/secret-management/$projectId/integrations/heroku/create' + | '/projects/secret-management/$projectId/integrations/laravel-forge/authorize' + | '/projects/secret-management/$projectId/integrations/laravel-forge/create' + | '/projects/secret-management/$projectId/integrations/netlify/create' + | '/projects/secret-management/$projectId/integrations/northflank/authorize' + | '/projects/secret-management/$projectId/integrations/northflank/create' + | '/projects/secret-management/$projectId/integrations/octopus-deploy/authorize' + | '/projects/secret-management/$projectId/integrations/octopus-deploy/create' + | '/projects/secret-management/$projectId/integrations/qovery/authorize' + | '/projects/secret-management/$projectId/integrations/qovery/create' + | '/projects/secret-management/$projectId/integrations/railway/authorize' + | '/projects/secret-management/$projectId/integrations/railway/create' + | '/projects/secret-management/$projectId/integrations/render/authorize' + | '/projects/secret-management/$projectId/integrations/render/create' + | '/projects/secret-management/$projectId/integrations/rundeck/authorize' + | '/projects/secret-management/$projectId/integrations/rundeck/create' + | '/projects/secret-management/$projectId/integrations/supabase/authorize' + | '/projects/secret-management/$projectId/integrations/supabase/create' + | '/projects/secret-management/$projectId/integrations/teamcity/authorize' + | '/projects/secret-management/$projectId/integrations/teamcity/create' + | '/projects/secret-management/$projectId/integrations/terraform-cloud/authorize' + | '/projects/secret-management/$projectId/integrations/terraform-cloud/create' + | '/projects/secret-management/$projectId/integrations/travisci/authorize' + | '/projects/secret-management/$projectId/integrations/travisci/create' + | '/projects/secret-management/$projectId/integrations/vercel/create' + | '/projects/secret-management/$projectId/integrations/windmill/authorize' + | '/projects/secret-management/$projectId/integrations/windmill/create' + | '/projects/secret-scanning/$projectId/data-sources/$type/$dataSourceId' + | '/projects/secret-management/$projectId/commits/$environment/$folderId' + | '/projects/secret-management/$projectId/integrations/azure-app-configuration/oauth2/callback' + | '/projects/secret-management/$projectId/integrations/azure-key-vault/oauth2/callback' + | '/projects/secret-management/$projectId/integrations/bitbucket/oauth2/callback' + | '/projects/secret-management/$projectId/integrations/gcp-secret-manager/oauth2/callback' + | '/projects/secret-management/$projectId/integrations/github/oauth2/callback' + | '/projects/secret-management/$projectId/integrations/gitlab/oauth2/callback' + | '/projects/secret-management/$projectId/integrations/heroku/oauth2/callback' + | '/projects/secret-management/$projectId/integrations/netlify/oauth2/callback' + | '/projects/secret-management/$projectId/integrations/secret-syncs/$destination/$syncId' + | '/projects/secret-management/$projectId/integrations/vercel/oauth2/callback' + | '/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId' + | '/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId/restore' id: | '__root__' | '/' @@ -5311,6 +5653,7 @@ export interface FileRouteTypes { | '/_authenticate/personal-settings/_layout/' | '/_restrict-login-signup/login/provider/error' | '/_restrict-login-signup/login/provider/success' + | '/_authenticate/_inject-org-details/_org-layout/integrations' | '/_authenticate/_inject-org-details/_org-layout/organization' | '/_authenticate/_inject-org-details/admin/_admin-layout' | '/_authenticate/_inject-org-details/admin/_admin-layout/' @@ -5328,7 +5671,6 @@ export interface FileRouteTypes { | '/_authenticate/_inject-org-details/_org-layout/organization/gateways' | '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing' | '/_authenticate/_inject-org-details/_org-layout/organization/settings' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId' | '/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId' | '/_authenticate/_inject-org-details/_org-layout/organization/app-connections/' | '/_authenticate/_inject-org-details/_org-layout/organization/gateways/' @@ -5342,152 +5684,168 @@ export interface FileRouteTypes { | '/_authenticate/_inject-org-details/admin/_admin-layout/resources/machine-identities' | '/_authenticate/_inject-org-details/admin/_admin-layout/resources/organizations' | '/_authenticate/_inject-org-details/admin/_admin-layout/resources/user-identities' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout' + | '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId' + | '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId' + | '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId' | '/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId/approval' | '/_authenticate/_inject-org-details/_org-layout/organization/settings/oauth/callback' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh' + | '/_authenticate/_inject-org-details/_org-layout/integrations/azure-app-configuration/oauth2/callback' + | '/_authenticate/_inject-org-details/_org-layout/integrations/azure-key-vault/oauth2/callback' + | '/_authenticate/_inject-org-details/_org-layout/integrations/bitbucket/oauth2/callback' + | '/_authenticate/_inject-org-details/_org-layout/integrations/gcp-secret-manager/oauth2/callback' + | '/_authenticate/_inject-org-details/_org-layout/integrations/github/oauth2/callback' + | '/_authenticate/_inject-org-details/_org-layout/integrations/gitlab/oauth2/callback' + | '/_authenticate/_inject-org-details/_org-layout/integrations/heroku/oauth2/callback' + | '/_authenticate/_inject-org-details/_org-layout/integrations/netlify/oauth2/callback' + | '/_authenticate/_inject-org-details/_org-layout/integrations/vercel/oauth2/callback' + | '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout' + | '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout' + | '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout' | '/_authenticate/_inject-org-details/_org-layout/organization/app-connections/$appConnection/oauth/callback' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/access-management' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/settings' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/groups/$groupId' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/identities/$identityId' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/members/$membershipId' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/roles/$roleSlug' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/alerting' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificate-authorities' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificates' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/settings' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout/kmip' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout/overview' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout/settings' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/allowlist' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/approval' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/overview' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/secret-rotation' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/settings' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/findings' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/settings' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/cas' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/certificates' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/overview' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/settings' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificate-templates' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/subscribers' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/data-sources' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificate-templates/' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/subscribers/' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/data-sources/' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/ca/$caName' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/subscribers/$subscriberName' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/$integrationId' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/select-integration-auth' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/secrets/$envSlug' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/ca/$caId' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/ssh-host-groups/$sshHostGroupId' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/pki-collections/$collectionId' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/azure-app-configuration/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/azure-key-vault/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/bitbucket/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/gcp-secret-manager/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/github/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/gitlab/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/heroku/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/netlify/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/vercel/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-parameter-store/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-parameter-store/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-secret-manager/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-secret-manager/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-app-configuration/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-devops/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-devops/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-key-vault/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-key-vault/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/bitbucket/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/checkly/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/checkly/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/circleci/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/circleci/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloud-66/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloud-66/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-pages/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-pages/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-workers/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-workers/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/codefresh/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/codefresh/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/databricks/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/databricks/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/digital-ocean-app-platform/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/digital-ocean-app-platform/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/flyio/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/flyio/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gcp-secret-manager/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gcp-secret-manager/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/github/auth-mode-selection' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/github/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gitlab/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gitlab/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hashicorp-vault/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hashicorp-vault/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hasura-cloud/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hasura-cloud/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/heroku/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/laravel-forge/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/laravel-forge/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/netlify/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/northflank/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/northflank/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/octopus-deploy/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/octopus-deploy/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/qovery/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/qovery/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/railway/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/railway/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/render/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/render/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/rundeck/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/rundeck/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/supabase/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/supabase/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/teamcity/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/teamcity/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/terraform-cloud/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/terraform-cloud/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/travisci/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/travisci/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/vercel/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/windmill/authorize' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/windmill/create' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/data-sources/$type/$dataSourceId' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-app-configuration/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-key-vault/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/bitbucket/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gcp-secret-manager/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/github/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gitlab/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/heroku/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/netlify/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/secret-syncs/$destination/$syncId' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/vercel/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/$commitId' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/$commitId/' - | '/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/$commitId/restore' + | '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/alerting' + | '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificate-authorities' + | '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificates' + | '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/settings' + | '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/kmip' + | '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/overview' + | '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/settings' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/allowlist' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/approval' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/overview' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/secret-rotation' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/settings' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/findings' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/settings' + | '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/cas' + | '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/certificates' + | '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/overview' + | '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/settings' + | '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/access-management' + | '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates' + | '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/subscribers' + | '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/access-management' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/access-management' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/access-management' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources' + | '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/access-management' + | '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates/' + | '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/subscribers/' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/' + | '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/ca/$caName' + | '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/subscribers/$subscriberName' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/$integrationId' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/select-integration-auth' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/secrets/$envSlug' + | '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/ca/$caId' + | '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/ssh-host-groups/$sshHostGroupId' + | '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/groups/$groupId' + | '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/identities/$identityId' + | '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/members/$membershipId' + | '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/pki-collections/$collectionId' + | '/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/roles/$roleSlug' + | '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/groups/$groupId' + | '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/identities/$identityId' + | '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/members/$membershipId' + | '/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/roles/$roleSlug' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/groups/$groupId' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/identities/$identityId' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/members/$membershipId' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/roles/$roleSlug' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/groups/$groupId' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/identities/$identityId' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/members/$membershipId' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/roles/$roleSlug' + | '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/groups/$groupId' + | '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/identities/$identityId' + | '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/members/$membershipId' + | '/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/roles/$roleSlug' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/auth-mode-selection' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/authorize' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/create' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/$type/$dataSourceId' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/oauth2/callback' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/oauth2/callback' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/oauth2/callback' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/oauth2/callback' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/oauth2/callback' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/oauth2/callback' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/oauth2/callback' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/oauth2/callback' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/secret-syncs/$destination/$syncId' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/oauth2/callback' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/' + | '/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/restore' fileRoutesById: FileRoutesById } @@ -5670,9 +6028,14 @@ export const routeTree = rootRoute "filePath": "organization/layout.tsx", "parent": "/_authenticate/_inject-org-details", "children": [ + "/_authenticate/_inject-org-details/_org-layout/integrations", "/_authenticate/_inject-org-details/_org-layout/organization", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId", - "/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId" + "/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId", + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId", + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId", + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId" ] }, "/_authenticate/_inject-org-details/admin": { @@ -5701,6 +6064,21 @@ export const routeTree = rootRoute "filePath": "auth/ProviderSuccessPage/route.tsx", "parent": "/_restrict-login-signup/login" }, + "/_authenticate/_inject-org-details/_org-layout/integrations": { + "filePath": "", + "parent": "/_authenticate/_inject-org-details/_org-layout", + "children": [ + "/_authenticate/_inject-org-details/_org-layout/integrations/azure-app-configuration/oauth2/callback", + "/_authenticate/_inject-org-details/_org-layout/integrations/azure-key-vault/oauth2/callback", + "/_authenticate/_inject-org-details/_org-layout/integrations/bitbucket/oauth2/callback", + "/_authenticate/_inject-org-details/_org-layout/integrations/gcp-secret-manager/oauth2/callback", + "/_authenticate/_inject-org-details/_org-layout/integrations/github/oauth2/callback", + "/_authenticate/_inject-org-details/_org-layout/integrations/gitlab/oauth2/callback", + "/_authenticate/_inject-org-details/_org-layout/integrations/heroku/oauth2/callback", + "/_authenticate/_inject-org-details/_org-layout/integrations/netlify/oauth2/callback", + "/_authenticate/_inject-org-details/_org-layout/integrations/vercel/oauth2/callback" + ] + }, "/_authenticate/_inject-org-details/_org-layout/organization": { "filePath": "", "parent": "/_authenticate/_inject-org-details/_org-layout", @@ -5810,13 +6188,6 @@ export const routeTree = rootRoute "/_authenticate/_inject-org-details/_org-layout/organization/settings/oauth/callback" ] }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId": { - "filePath": "", - "parent": "/_authenticate/_inject-org-details/_org-layout", - "children": [ - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout" - ] - }, "/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId": { "filePath": "", "parent": "/_authenticate/_inject-org-details/_org-layout", @@ -5872,17 +6243,39 @@ export const routeTree = rootRoute "filePath": "admin/UserIdentitiesResourcesPage/route.tsx", "parent": "/_authenticate/_inject-org-details/admin/_admin-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout": { - "filePath": "project/layout.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId", + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId": { + "filePath": "", + "parent": "/_authenticate/_inject-org-details/_org-layout", "children": [ - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh" + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout" + ] + }, + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId": { + "filePath": "", + "parent": "/_authenticate/_inject-org-details/_org-layout", + "children": [ + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout" + ] + }, + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId": { + "filePath": "", + "parent": "/_authenticate/_inject-org-details/_org-layout", + "children": [ + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout" + ] + }, + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId": { + "filePath": "", + "parent": "/_authenticate/_inject-org-details/_org-layout", + "children": [ + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout" + ] + }, + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId": { + "filePath": "", + "parent": "/_authenticate/_inject-org-details/_org-layout", + "children": [ + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout" ] }, "/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId/approval": { @@ -5893,748 +6286,787 @@ export const routeTree = rootRoute "filePath": "organization/SettingsPage/OauthCallbackPage/route.tsx", "parent": "/_authenticate/_inject-org-details/_org-layout/organization/settings" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout": { - "filePath": "project/layout-general.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout", + "/_authenticate/_inject-org-details/_org-layout/integrations/azure-app-configuration/oauth2/callback": { + "filePath": "secret-manager/integrations/route-azure-app-configurations-oauth-redirect.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/integrations" + }, + "/_authenticate/_inject-org-details/_org-layout/integrations/azure-key-vault/oauth2/callback": { + "filePath": "secret-manager/integrations/route-azure-key-vault-oauth-redirect.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/integrations" + }, + "/_authenticate/_inject-org-details/_org-layout/integrations/bitbucket/oauth2/callback": { + "filePath": "secret-manager/integrations/route-bitbucket-oauth-redirect.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/integrations" + }, + "/_authenticate/_inject-org-details/_org-layout/integrations/gcp-secret-manager/oauth2/callback": { + "filePath": "secret-manager/integrations/route-gcp-oauth-redirect.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/integrations" + }, + "/_authenticate/_inject-org-details/_org-layout/integrations/github/oauth2/callback": { + "filePath": "secret-manager/integrations/route-github-oauth-redirect.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/integrations" + }, + "/_authenticate/_inject-org-details/_org-layout/integrations/gitlab/oauth2/callback": { + "filePath": "secret-manager/integrations/route-gitlab-oauth-redirect.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/integrations" + }, + "/_authenticate/_inject-org-details/_org-layout/integrations/heroku/oauth2/callback": { + "filePath": "secret-manager/integrations/route-heroku-oauth-redirect.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/integrations" + }, + "/_authenticate/_inject-org-details/_org-layout/integrations/netlify/oauth2/callback": { + "filePath": "secret-manager/integrations/route-netlify-oauth-redirect.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/integrations" + }, + "/_authenticate/_inject-org-details/_org-layout/integrations/vercel/oauth2/callback": { + "filePath": "secret-manager/integrations/route-vercel-oauth-redirect.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/integrations" + }, + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout": { + "filePath": "cert-manager/layout.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId", "children": [ - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/access-management", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/settings", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/groups/$groupId", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/identities/$identityId", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/members/$membershipId", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/roles/$roleSlug" + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/alerting", + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificate-authorities", + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificates", + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/settings", + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/access-management", + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates", + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/subscribers", + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/ca/$caName", + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/groups/$groupId", + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/identities/$identityId", + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/members/$membershipId", + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/pki-collections/$collectionId", + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/roles/$roleSlug" ] }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager": { - "filePath": "", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout", + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout": { + "filePath": "kms/layout.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId", "children": [ - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout" + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/kmip", + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/overview", + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/settings", + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/access-management", + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/groups/$groupId", + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/identities/$identityId", + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/members/$membershipId", + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/roles/$roleSlug" ] }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations": { - "filePath": "", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout": { + "filePath": "secret-manager/layout.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId", "children": [ - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/azure-app-configuration/oauth2/callback", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/azure-key-vault/oauth2/callback", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/bitbucket/oauth2/callback", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/gcp-secret-manager/oauth2/callback", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/github/oauth2/callback", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/gitlab/oauth2/callback", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/heroku/oauth2/callback", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/netlify/oauth2/callback", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/vercel/oauth2/callback" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/allowlist", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/approval", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/overview", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/secret-rotation", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/settings", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/access-management", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/secrets/$envSlug", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/groups/$groupId", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/identities/$identityId", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/members/$membershipId", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/roles/$roleSlug", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId" ] }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms": { - "filePath": "", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout": { + "filePath": "secret-scanning/layout.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId", "children": [ - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/findings", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/settings", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/access-management", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/groups/$groupId", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/identities/$identityId", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/members/$membershipId", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/roles/$roleSlug" ] }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager": { - "filePath": "", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout", + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout": { + "filePath": "ssh/layout.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId", "children": [ - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout" - ] - }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning": { - "filePath": "", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout", - "children": [ - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout" - ] - }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh": { - "filePath": "", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout", - "children": [ - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout" + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/cas", + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/certificates", + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/overview", + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/settings", + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/access-management", + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/ca/$caId", + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/ssh-host-groups/$sshHostGroupId", + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/groups/$groupId", + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/identities/$identityId", + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/members/$membershipId", + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/roles/$roleSlug" ] }, "/_authenticate/_inject-org-details/_org-layout/organization/app-connections/$appConnection/oauth/callback": { "filePath": "organization/AppConnections/OauthCallbackPage/route.tsx", "parent": "/_authenticate/_inject-org-details/_org-layout/organization/app-connections" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/access-management": { - "filePath": "project/AccessControlPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout" - }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/settings": { - "filePath": "project/SettingsPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout" - }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout": { - "filePath": "cert-manager/layout.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager", - "children": [ - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/alerting", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificate-authorities", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificates", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/settings", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificate-templates", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/subscribers", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/ca/$caName", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/pki-collections/$collectionId" - ] - }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout": { - "filePath": "kms/layout.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms", - "children": [ - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout/kmip", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout/overview", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout/settings" - ] - }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout": { - "filePath": "secret-manager/layout.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager", - "children": [ - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/allowlist", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/approval", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/overview", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/secret-rotation", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/settings", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/secrets/$envSlug", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId" - ] - }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout": { - "filePath": "secret-scanning/layout.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning", - "children": [ - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/findings", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/settings", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/data-sources" - ] - }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout": { - "filePath": "ssh/layout.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh", - "children": [ - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/cas", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/certificates", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/overview", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/settings", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/ca/$caId", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/ssh-host-groups/$sshHostGroupId" - ] - }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/groups/$groupId": { - "filePath": "project/GroupDetailsByIDPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout" - }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/identities/$identityId": { - "filePath": "project/IdentityDetailsByIDPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout" - }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/members/$membershipId": { - "filePath": "project/MemberDetailsByIDPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout" - }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout/roles/$roleSlug": { - "filePath": "project/RoleDetailsBySlugPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/_project-general-layout" - }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/alerting": { + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/alerting": { "filePath": "cert-manager/AlertingPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificate-authorities": { + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificate-authorities": { "filePath": "cert-manager/CertificateAuthoritiesPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificates": { + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificates": { "filePath": "cert-manager/CertificatesPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/settings": { + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/settings": { "filePath": "cert-manager/SettingsPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout/kmip": { + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/kmip": { "filePath": "kms/KmipPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout/overview": { + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/overview": { "filePath": "kms/OverviewPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout/settings": { + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/settings": { "filePath": "kms/SettingsPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/kms/_kms-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/allowlist": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/allowlist": { "filePath": "secret-manager/IPAllowlistPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/approval": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/approval": { "filePath": "secret-manager/SecretApprovalsPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/overview": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/overview": { "filePath": "secret-manager/OverviewPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/secret-rotation": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/secret-rotation": { "filePath": "secret-manager/SecretRotationPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/settings": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/settings": { "filePath": "secret-manager/SettingsPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/findings": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/findings": { "filePath": "secret-scanning/SecretScanningFindingsPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/settings": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/settings": { "filePath": "secret-scanning/SettingsPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/cas": { + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/cas": { "filePath": "ssh/SshCasPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/certificates": { + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/certificates": { "filePath": "ssh/SshCertsPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/overview": { + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/overview": { "filePath": "ssh/SshHostsPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/settings": { + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/settings": { "filePath": "ssh/SettingsPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificate-templates": { + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/access-management": { + "filePath": "project/AccessControlPage/route-cert-manager.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout" + }, + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates": { "filePath": "", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout", "children": [ - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificate-templates/" + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates/" ] }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/subscribers": { + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/subscribers": { "filePath": "", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout", "children": [ - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/subscribers/", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/subscribers/$subscriberName" + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/subscribers/", + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/subscribers/$subscriberName" ] }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations": { + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/access-management": { + "filePath": "project/AccessControlPage/route-kms.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout" + }, + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/access-management": { + "filePath": "project/AccessControlPage/route-secret-manager.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout" + }, + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations": { "filePath": "", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout", "children": [ - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/$integrationId", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/select-integration-auth", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-parameter-store/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-parameter-store/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-secret-manager/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-secret-manager/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-app-configuration/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-devops/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-devops/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-key-vault/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-key-vault/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/bitbucket/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/checkly/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/checkly/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/circleci/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/circleci/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloud-66/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloud-66/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-pages/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-pages/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-workers/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-workers/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/codefresh/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/codefresh/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/databricks/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/databricks/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/digital-ocean-app-platform/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/digital-ocean-app-platform/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/flyio/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/flyio/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gcp-secret-manager/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gcp-secret-manager/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/github/auth-mode-selection", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/github/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gitlab/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gitlab/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hashicorp-vault/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hashicorp-vault/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hasura-cloud/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hasura-cloud/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/heroku/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/laravel-forge/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/laravel-forge/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/netlify/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/northflank/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/northflank/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/octopus-deploy/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/octopus-deploy/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/qovery/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/qovery/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/railway/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/railway/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/render/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/render/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/rundeck/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/rundeck/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/supabase/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/supabase/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/teamcity/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/teamcity/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/terraform-cloud/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/terraform-cloud/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/travisci/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/travisci/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/vercel/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/windmill/authorize", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/windmill/create", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-app-configuration/oauth2/callback", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-key-vault/oauth2/callback", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/bitbucket/oauth2/callback", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gcp-secret-manager/oauth2/callback", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/github/oauth2/callback", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gitlab/oauth2/callback", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/heroku/oauth2/callback", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/netlify/oauth2/callback", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/secret-syncs/$destination/$syncId", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/vercel/oauth2/callback" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/$integrationId", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/select-integration-auth", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/auth-mode-selection", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/authorize", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/create", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/oauth2/callback", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/oauth2/callback", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/oauth2/callback", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/oauth2/callback", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/oauth2/callback", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/oauth2/callback", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/oauth2/callback", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/oauth2/callback", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/secret-syncs/$destination/$syncId", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/oauth2/callback" ] }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/data-sources": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/access-management": { + "filePath": "project/AccessControlPage/route-secret-scanning.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout" + }, + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources": { "filePath": "", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout", "children": [ - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/data-sources/", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/data-sources/$type/$dataSourceId" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/$type/$dataSourceId" ] }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificate-templates/": { + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/access-management": { + "filePath": "project/AccessControlPage/route-ssh.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout" + }, + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates/": { "filePath": "cert-manager/PkiTemplateListPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/certificate-templates" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/subscribers/": { + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/subscribers/": { "filePath": "cert-manager/PkiSubscribersPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/subscribers" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/subscribers" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/": { "filePath": "secret-manager/IntegrationsListPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/data-sources/": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/": { "filePath": "secret-scanning/SecretScanningDataSourcesPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/data-sources" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/ca/$caName": { + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/ca/$caName": { "filePath": "cert-manager/CertAuthDetailsByIDPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/subscribers/$subscriberName": { + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/subscribers/$subscriberName": { "filePath": "cert-manager/PkiSubscriberDetailsByIDPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/subscribers" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/subscribers" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/$integrationId": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/$integrationId": { "filePath": "secret-manager/IntegrationsDetailsByIDPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/select-integration-auth": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/select-integration-auth": { "filePath": "secret-manager/integrations/SelectIntegrationAuthPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/secrets/$envSlug": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/secrets/$envSlug": { "filePath": "secret-manager/SecretDashboardPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/ca/$caId": { + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/ca/$caId": { "filePath": "ssh/SshCaByIDPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout/ssh-host-groups/$sshHostGroupId": { + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/ssh-host-groups/$sshHostGroupId": { "filePath": "ssh/SshHostGroupDetailsByIDPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/ssh/_ssh-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout/pki-collections/$collectionId": { + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/groups/$groupId": { + "filePath": "project/GroupDetailsByIDPage/route-cert-manager.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout" + }, + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/identities/$identityId": { + "filePath": "project/IdentityDetailsByIDPage/route-cert-manager.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout" + }, + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/members/$membershipId": { + "filePath": "project/MemberDetailsByIDPage/route-cert-manager.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout" + }, + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/pki-collections/$collectionId": { "filePath": "cert-manager/PkiCollectionDetailsByIDPage/routes.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/cert-manager/_cert-manager-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/azure-app-configuration/oauth2/callback": { - "filePath": "secret-manager/integrations/route-azure-app-configurations-oauth-redirect.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations" + "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/roles/$roleSlug": { + "filePath": "project/RoleDetailsBySlugPage/route-cert-manager.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/azure-key-vault/oauth2/callback": { - "filePath": "secret-manager/integrations/route-azure-key-vault-oauth-redirect.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations" + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/groups/$groupId": { + "filePath": "project/GroupDetailsByIDPage/route-kms.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/bitbucket/oauth2/callback": { - "filePath": "secret-manager/integrations/route-bitbucket-oauth-redirect.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations" + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/identities/$identityId": { + "filePath": "project/IdentityDetailsByIDPage/route-kms.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/gcp-secret-manager/oauth2/callback": { - "filePath": "secret-manager/integrations/route-gcp-oauth-redirect.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations" + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/members/$membershipId": { + "filePath": "project/MemberDetailsByIDPage/route-kms.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/github/oauth2/callback": { - "filePath": "secret-manager/integrations/route-github-oauth-redirect.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations" + "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/roles/$roleSlug": { + "filePath": "project/RoleDetailsBySlugPage/route-kms.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/gitlab/oauth2/callback": { - "filePath": "secret-manager/integrations/route-gitlab-oauth-redirect.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/groups/$groupId": { + "filePath": "project/GroupDetailsByIDPage/route-secret-manager.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/heroku/oauth2/callback": { - "filePath": "secret-manager/integrations/route-heroku-oauth-redirect.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/identities/$identityId": { + "filePath": "project/IdentityDetailsByIDPage/route-secret-manager.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/netlify/oauth2/callback": { - "filePath": "secret-manager/integrations/route-netlify-oauth-redirect.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/members/$membershipId": { + "filePath": "project/MemberDetailsByIDPage/route-secret-manager.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations/vercel/oauth2/callback": { - "filePath": "secret-manager/integrations/route-vercel-oauth-redirect.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/integrations" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/roles/$roleSlug": { + "filePath": "project/RoleDetailsBySlugPage/route-secret-manager.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-parameter-store/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/groups/$groupId": { + "filePath": "project/GroupDetailsByIDPage/route-secret-scanning.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout" + }, + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/identities/$identityId": { + "filePath": "project/IdentityDetailsByIDPage/route-secret-scanning.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout" + }, + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/members/$membershipId": { + "filePath": "project/MemberDetailsByIDPage/route-secret-scanning.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout" + }, + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/roles/$roleSlug": { + "filePath": "project/RoleDetailsBySlugPage/route-secret-scanning.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout" + }, + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/groups/$groupId": { + "filePath": "project/GroupDetailsByIDPage/route-ssh.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout" + }, + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/identities/$identityId": { + "filePath": "project/IdentityDetailsByIDPage/route-ssh.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout" + }, + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/members/$membershipId": { + "filePath": "project/MemberDetailsByIDPage/route-ssh.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout" + }, + "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/roles/$roleSlug": { + "filePath": "project/RoleDetailsBySlugPage/route-ssh.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout" + }, + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/authorize": { "filePath": "secret-manager/integrations/AwsParameterStoreAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-parameter-store/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/create": { "filePath": "secret-manager/integrations/AwsParameterStoreConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-secret-manager/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/authorize": { "filePath": "secret-manager/integrations/AwsSecretManagerAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/aws-secret-manager/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/create": { "filePath": "secret-manager/integrations/AwsSecretManagerConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-app-configuration/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/create": { "filePath": "secret-manager/integrations/AzureAppConfigurationConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-devops/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/authorize": { "filePath": "secret-manager/integrations/AzureDevopsAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-devops/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/create": { "filePath": "secret-manager/integrations/AzureDevopsConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-key-vault/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/authorize": { "filePath": "secret-manager/integrations/AzureKeyVaultAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-key-vault/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/create": { "filePath": "secret-manager/integrations/AzureKeyVaultConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/bitbucket/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/create": { "filePath": "secret-manager/integrations/BitbucketConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/checkly/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/authorize": { "filePath": "secret-manager/integrations/ChecklyAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/checkly/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/create": { "filePath": "secret-manager/integrations/ChecklyConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/circleci/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/authorize": { "filePath": "secret-manager/integrations/CircleCIAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/circleci/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/create": { "filePath": "secret-manager/integrations/CircleCIConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloud-66/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/authorize": { "filePath": "secret-manager/integrations/Cloud66AuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloud-66/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/create": { "filePath": "secret-manager/integrations/Cloud66ConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-pages/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/authorize": { "filePath": "secret-manager/integrations/CloudflarePagesAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-pages/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/create": { "filePath": "secret-manager/integrations/CloudflarePagesConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-workers/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/authorize": { "filePath": "secret-manager/integrations/CloudflareWorkersAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/cloudflare-workers/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/create": { "filePath": "secret-manager/integrations/CloudflareWorkersConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/codefresh/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/authorize": { "filePath": "secret-manager/integrations/CodefreshAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/codefresh/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/create": { "filePath": "secret-manager/integrations/CodefreshConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/databricks/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/authorize": { "filePath": "secret-manager/integrations/DatabricksAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/databricks/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/create": { "filePath": "secret-manager/integrations/DatabricksConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/digital-ocean-app-platform/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/authorize": { "filePath": "secret-manager/integrations/DigitalOceanAppPlatformAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/digital-ocean-app-platform/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/create": { "filePath": "secret-manager/integrations/DigitalOceanAppPlatformConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/flyio/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/authorize": { "filePath": "secret-manager/integrations/FlyioAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/flyio/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/create": { "filePath": "secret-manager/integrations/FlyioConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gcp-secret-manager/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/authorize": { "filePath": "secret-manager/integrations/GcpSecretManagerAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gcp-secret-manager/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/create": { "filePath": "secret-manager/integrations/GcpSecretManagerConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/github/auth-mode-selection": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/auth-mode-selection": { "filePath": "secret-manager/integrations/GithubAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/github/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/create": { "filePath": "secret-manager/integrations/GithubConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gitlab/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/authorize": { "filePath": "secret-manager/integrations/GitlabAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gitlab/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/create": { "filePath": "secret-manager/integrations/GitlabConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hashicorp-vault/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/authorize": { "filePath": "secret-manager/integrations/HashicorpVaultAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hashicorp-vault/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/create": { "filePath": "secret-manager/integrations/HashicorpVaultConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hasura-cloud/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/authorize": { "filePath": "secret-manager/integrations/HasuraCloudAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/hasura-cloud/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/create": { "filePath": "secret-manager/integrations/HasuraCloudConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/heroku/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/create": { "filePath": "secret-manager/integrations/HerokuConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/laravel-forge/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/authorize": { "filePath": "secret-manager/integrations/LaravelForgeAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/laravel-forge/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/create": { "filePath": "secret-manager/integrations/LaravelForgeConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/netlify/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/create": { "filePath": "secret-manager/integrations/NetlifyConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/northflank/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/authorize": { "filePath": "secret-manager/integrations/NorthflankAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/northflank/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/create": { "filePath": "secret-manager/integrations/NorthflankConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/octopus-deploy/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/authorize": { "filePath": "secret-manager/integrations/OctopusDeployAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/octopus-deploy/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/create": { "filePath": "secret-manager/integrations/OctopusDeployConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/qovery/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/authorize": { "filePath": "secret-manager/integrations/QoveryAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/qovery/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/create": { "filePath": "secret-manager/integrations/QoveryConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/railway/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/authorize": { "filePath": "secret-manager/integrations/RailwayAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/railway/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/create": { "filePath": "secret-manager/integrations/RailwayConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/render/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/authorize": { "filePath": "secret-manager/integrations/RenderAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/render/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/create": { "filePath": "secret-manager/integrations/RenderConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/rundeck/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/authorize": { "filePath": "secret-manager/integrations/RundeckAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/rundeck/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/create": { "filePath": "secret-manager/integrations/RundeckConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/supabase/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/authorize": { "filePath": "secret-manager/integrations/SupabaseAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/supabase/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/create": { "filePath": "secret-manager/integrations/SupabaseConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/teamcity/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/authorize": { "filePath": "secret-manager/integrations/TeamcityAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/teamcity/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/create": { "filePath": "secret-manager/integrations/TeamcityConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/terraform-cloud/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/authorize": { "filePath": "secret-manager/integrations/TerraformCloudAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/terraform-cloud/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/create": { "filePath": "secret-manager/integrations/TerraformCloudConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/travisci/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/authorize": { "filePath": "secret-manager/integrations/TravisCIAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/travisci/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/create": { "filePath": "secret-manager/integrations/TravisCIConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/vercel/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/create": { "filePath": "secret-manager/integrations/VercelConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/windmill/authorize": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/authorize": { "filePath": "secret-manager/integrations/WindmillAuthorizePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/windmill/create": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/create": { "filePath": "secret-manager/integrations/WindmillConfigurePage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/data-sources/$type/$dataSourceId": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/$type/$dataSourceId": { "filePath": "secret-scanning/SecretScanningDataSourceByIdPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-scanning/_secret-scanning-layout/data-sources" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId": { "filePath": "", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout", "children": [ - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/$commitId" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId" ] }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/": { "filePath": "secret-manager/CommitsPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-app-configuration/oauth2/callback": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/oauth2/callback": { "filePath": "secret-manager/integrations/AzureAppConfigurationOauthCallbackPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/azure-key-vault/oauth2/callback": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/oauth2/callback": { "filePath": "secret-manager/integrations/AzureKeyVaultOauthCallbackPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/bitbucket/oauth2/callback": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/oauth2/callback": { "filePath": "secret-manager/integrations/BitbucketOauthCallbackPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gcp-secret-manager/oauth2/callback": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/oauth2/callback": { "filePath": "secret-manager/integrations/GcpSecretManagerOauthCallbackPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/github/oauth2/callback": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/oauth2/callback": { "filePath": "secret-manager/integrations/GithubOauthCallbackPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/gitlab/oauth2/callback": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/oauth2/callback": { "filePath": "secret-manager/integrations/GitlabOauthCallbackPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/heroku/oauth2/callback": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/oauth2/callback": { "filePath": "secret-manager/integrations/HerokuOauthCallbackPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/netlify/oauth2/callback": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/oauth2/callback": { "filePath": "secret-manager/integrations/NetlifyOauthCallbackPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/secret-syncs/$destination/$syncId": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/secret-syncs/$destination/$syncId": { "filePath": "secret-manager/SecretSyncDetailsByIDPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations/vercel/oauth2/callback": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/oauth2/callback": { "filePath": "secret-manager/integrations/VercelOauthCallbackPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/$commitId": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId": { "filePath": "", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId", + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId", "children": [ - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/$commitId/", - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/$commitId/restore" + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/", + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/restore" ] }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/$commitId/": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/": { "filePath": "secret-manager/CommitDetailsPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/$commitId" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId" }, - "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/$commitId/restore": { + "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/restore": { "filePath": "secret-manager/CommitDetailsPage/components/RollbackPreviewTab/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/projects/$projectId/_project-layout/secret-manager/_secret-manager-layout/commits/$environment/$folderId/$commitId" + "parent": "/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId" } } } diff --git a/frontend/src/routes.ts b/frontend/src/routes.ts index 35bbca2d7..353aa7a5d 100644 --- a/frontend/src/routes.ts +++ b/frontend/src/routes.ts @@ -45,7 +45,7 @@ const organizationRoutes = route("/organization", [ route("/gateways", [index("organization/Gateways/GatewayListPage/route.tsx")]) ]); -const secretManagerRoutes = route("/secret-manager", [ +const secretManagerRoutes = route("/projects/secret-management/$projectId", [ layout("secret-manager-layout", "secret-manager/layout.tsx", [ route("/overview", "secret-manager/OverviewPage/route.tsx"), route("/secrets/$envSlug", "secret-manager/SecretDashboardPage/route.tsx"), @@ -63,6 +63,11 @@ const secretManagerRoutes = route("/secret-manager", [ ) ]) ]), + route("/access-management", "project/AccessControlPage/route-secret-manager.tsx"), + route("/roles/$roleSlug", "project/RoleDetailsBySlugPage/route-secret-manager.tsx"), + route("/identities/$identityId", "project/IdentityDetailsByIDPage/route-secret-manager.tsx"), + route("/members/$membershipId", "project/MemberDetailsByIDPage/route-secret-manager.tsx"), + route("/groups/$groupId", "project/GroupDetailsByIDPage/route-secret-manager.tsx"), route("/integrations", [ index("secret-manager/IntegrationsListPage/route.tsx"), route("/$integrationId", "secret-manager/IntegrationsDetailsByIDPage/route.tsx"), @@ -294,7 +299,7 @@ const secretManagerIntegrationsRedirect = route("/integrations", [ ) ]); -const certManagerRoutes = route("/cert-manager", [ +const certManagerRoutes = route("/projects/cert-management/$projectId", [ layout("cert-manager-layout", "cert-manager/layout.tsx", [ route("/subscribers", [ index("cert-manager/PkiSubscribersPage/route.tsx"), @@ -306,49 +311,60 @@ const certManagerRoutes = route("/cert-manager", [ route("/alerting", "cert-manager/AlertingPage/route.tsx"), route("/ca/$caName", "cert-manager/CertAuthDetailsByIDPage/route.tsx"), route("/pki-collections/$collectionId", "cert-manager/PkiCollectionDetailsByIDPage/routes.tsx"), - route("/settings", "cert-manager/SettingsPage/route.tsx") + route("/settings", "cert-manager/SettingsPage/route.tsx"), + route("/access-management", "project/AccessControlPage/route-cert-manager.tsx"), + route("/roles/$roleSlug", "project/RoleDetailsBySlugPage/route-cert-manager.tsx"), + route("/identities/$identityId", "project/IdentityDetailsByIDPage/route-cert-manager.tsx"), + route("/members/$membershipId", "project/MemberDetailsByIDPage/route-cert-manager.tsx"), + route("/groups/$groupId", "project/GroupDetailsByIDPage/route-cert-manager.tsx") ]) ]); -const kmsRoutes = route("/kms", [ +const kmsRoutes = route("/projects/kms/$projectId", [ layout("kms-layout", "kms/layout.tsx", [ route("/overview", "kms/OverviewPage/route.tsx"), route("/kmip", "kms/KmipPage/route.tsx"), - route("/settings", "kms/SettingsPage/route.tsx") + route("/settings", "kms/SettingsPage/route.tsx"), + route("/access-management", "project/AccessControlPage/route-kms.tsx"), + route("/roles/$roleSlug", "project/RoleDetailsBySlugPage/route-kms.tsx"), + route("/identities/$identityId", "project/IdentityDetailsByIDPage/route-kms.tsx"), + route("/members/$membershipId", "project/MemberDetailsByIDPage/route-kms.tsx"), + route("/groups/$groupId", "project/GroupDetailsByIDPage/route-kms.tsx") ]) ]); -const sshRoutes = route("/ssh", [ +const sshRoutes = route("/projects/ssh/$projectId", [ layout("ssh-layout", "ssh/layout.tsx", [ route("/overview", "ssh/SshHostsPage/route.tsx"), route("/certificates", "ssh/SshCertsPage/route.tsx"), route("/cas", "ssh/SshCasPage/route.tsx"), route("/ca/$caId", "ssh/SshCaByIDPage/route.tsx"), route("/ssh-host-groups/$sshHostGroupId", "ssh/SshHostGroupDetailsByIDPage/route.tsx"), - route("/settings", "ssh/SettingsPage/route.tsx") + route("/settings", "ssh/SettingsPage/route.tsx"), + route("/access-management", "project/AccessControlPage/route-ssh.tsx"), + route("/roles/$roleSlug", "project/RoleDetailsBySlugPage/route-ssh.tsx"), + route("/identities/$identityId", "project/IdentityDetailsByIDPage/route-ssh.tsx"), + route("/members/$membershipId", "project/MemberDetailsByIDPage/route-ssh.tsx"), + route("/groups/$groupId", "project/GroupDetailsByIDPage/route-ssh.tsx") ]) ]); -const secretScanningRoutes = route("/secret-scanning", [ +const secretScanningRoutes = route("/projects/secret-scanning/$projectId", [ layout("secret-scanning-layout", "secret-scanning/layout.tsx", [ route("/data-sources", [ index("secret-scanning/SecretScanningDataSourcesPage/route.tsx"), route("/$type/$dataSourceId", "secret-scanning/SecretScanningDataSourceByIdPage/route.tsx") ]), route("/findings", "secret-scanning/SecretScanningFindingsPage/route.tsx"), - route("/settings", "secret-scanning/SettingsPage/route.tsx") + route("/settings", "secret-scanning/SettingsPage/route.tsx"), + route("/access-management", "project/AccessControlPage/route-secret-scanning.tsx"), + route("/roles/$roleSlug", "project/RoleDetailsBySlugPage/route-secret-scanning.tsx"), + route("/identities/$identityId", "project/IdentityDetailsByIDPage/route-secret-scanning.tsx"), + route("/members/$membershipId", "project/MemberDetailsByIDPage/route-secret-scanning.tsx"), + route("/groups/$groupId", "project/GroupDetailsByIDPage/route-secret-scanning.tsx") ]) ]); -const projectGeneralRoutes = layout("project-general-layout", "project/layout-general.tsx", [ - route("/access-management", "project/AccessControlPage/route.tsx"), - route("/roles/$roleSlug", "project/RoleDetailsBySlugPage/route.tsx"), - route("/identities/$identityId", "project/IdentityDetailsByIDPage/route.tsx"), - route("/members/$membershipId", "project/MemberDetailsByIDPage/route.tsx"), - route("/groups/$groupId", "project/GroupDetailsByIDPage/route.tsx"), - route("/settings", "project/SettingsPage/route.tsx") -]); - export const routes = rootRoute("root.tsx", [ index("index.tsx"), route("/shared/secret/$secretId", "public/ViewSharedSecretByIDPage/route.tsx"), @@ -389,17 +405,12 @@ export const routes = rootRoute("root.tsx", [ route("/secret-manager/$projectId", [ route("/approval", "secret-manager/redirects/redirect-approval-page.tsx") ]), - route("/projects/$projectId", [ - layout("project-layout", "project/layout.tsx", [ - projectGeneralRoutes, - secretManagerRoutes, - secretManagerIntegrationsRedirect, - certManagerRoutes, - kmsRoutes, - sshRoutes, - secretScanningRoutes - ]) - ]) + secretManagerRoutes, + secretManagerIntegrationsRedirect, + certManagerRoutes, + kmsRoutes, + sshRoutes, + secretScanningRoutes ]) ]) ])
- {` ${t("common.no-mobile")} `} -
Audit History
{workspace.name}
+ {getProjectTitle(workspace.type)}{" "} + {workspace.description ? `- ${workspace.description}` : ""} +
+ {getProjectTitle(workspace.type)} +
+ {workspace.description || "No description"} +
Machine Identities
Select a commit to view details
No details found for this commit
Error parsing commit details
- Commited by - {actorDisplay} - on - - {formatDisplayDate( - parsedCommitDetails.changes?.createdAt || new Date().toISOString() - )} - - {parsedCommitDetails.changes?.isLatest && ( - (Latest) - )} -
Restore Options
No changed items found
{key}
Secret Snapshots have been officially renamed to Commits. Going forward, all secret changes will be tracked as Commits. If you made changes before this update, you can diff --git a/frontend/src/pages/secret-manager/CommitsPage/components/CommitHistoryTab/CommitHistoryTab.tsx b/frontend/src/pages/secret-manager/CommitsPage/components/CommitHistoryTab/CommitHistoryTab.tsx index 8f529ba86..58191f389 100644 --- a/frontend/src/pages/secret-manager/CommitsPage/components/CommitHistoryTab/CommitHistoryTab.tsx +++ b/frontend/src/pages/secret-manager/CommitsPage/components/CommitHistoryTab/CommitHistoryTab.tsx @@ -1,29 +1,17 @@ -import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { useCallback, useEffect, useRef, useState } from "react"; import { faArrowDownWideShort, faArrowUpWideShort, + faCodeCommit, faCopy, faSearch } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { format, formatDistanceToNow } from "date-fns"; +import { formatDistanceToNow } from "date-fns"; -import { Button, Input, Spinner } from "@app/components/v2"; +import { Button, ContentLoader, EmptyState, IconButton, Input } from "@app/components/v2"; import { CopyButton } from "@app/components/v2/CopyButton"; -import { useGetFolderCommitHistory } from "@app/hooks/api/folderCommits"; - -interface CommitActorMetadata { - email?: string; - name?: string; -} - -interface Commit { - id: string; - message: string; - createdAt: string; - actorType: string; - actorMetadata?: CommitActorMetadata; -} +import { Commit, useGetFolderCommitHistory } from "@app/hooks/api/folderCommits"; const formatTimeAgo = (timestamp: string): string => { return formatDistanceToNow(new Date(timestamp), { addSuffix: true }); @@ -40,58 +28,40 @@ const CommitItem = ({ onSelectCommit: (commitId: string, tab: string) => void; }) => { return ( -
- - {commit.actorMetadata?.email || commit.actorMetadata?.name || commit.actorType} - committed - {formatTimeAgo(commit.createdAt)} - -
committed
- {commit.id?.substring(0, 11)} -
+ {commit.message} +
+ {commit.actorMetadata?.email || commit.actorMetadata?.name || commit.actorType}{" "} + committed {formatTimeAgo(commit.createdAt)} +
+ {commit.id?.substring(0, 11)} +
Commit History
No matching commits found. Try a different search term.
+ Review pending changes and commit them to apply the updates. +