diff --git a/backend/src/lib/api-docs/constants.ts b/backend/src/lib/api-docs/constants.ts index 269944d2d..f241a8b3a 100644 --- a/backend/src/lib/api-docs/constants.ts +++ b/backend/src/lib/api-docs/constants.ts @@ -2504,9 +2504,9 @@ export const SecretSyncs = { projectName: "The name of the Supabase project to sync secrets to." }, BITBUCKET: { - workspace: "The Bitbucket Workspace slug to sync secrets to.", - repository: "The Bitbucket Repository slug to sync secrets to.", - environment: "The Bitbucket Deployment Environment uuid to sync secrets to." + 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." } } }; 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 f610a54fd..0391063c7 100644 --- a/backend/src/services/app-connection/bitbucket/bitbucket-connection-fns.ts +++ b/backend/src/services/app-connection/bitbucket/bitbucket-connection-fns.ts @@ -22,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" } }); @@ -58,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" }; @@ -90,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" }; @@ -125,7 +129,7 @@ export const listBitbucketEnvironments = async ( const { email, apiToken } = appConnection.credentials; const headers = { - Authorization: `Basic ${Buffer.from(`${email}:${apiToken}`).toString("base64")}`, + Authorization: createAuthHeader(email, apiToken), Accept: "application/json" }; @@ -134,7 +138,9 @@ export const listBitbucketEnvironments = async ( let environmentsUrl = `${IntegrationUrls.BITBUCKET_API_URL}/2.0/repositories/${encodeURIComponent(workspaceSlug)}/${encodeURIComponent(repositorySlug)}/environments?pagelen=100`; - while (hasNextPage) { + let iterationCount = 0; + // Limit to 10 iterations, fetching at most 10 * 100 = 1000 environments + while (hasNextPage && iterationCount < 100) { // eslint-disable-next-line no-await-in-loop const { data }: { data: { values: TBitbucketEnvironment[]; next: string } } = await request.get(environmentsUrl, { headers @@ -149,6 +155,7 @@ export const listBitbucketEnvironments = async ( } else { hasNextPage = false; } + iterationCount += 1; } return environments; diff --git a/backend/src/services/secret-sync/bitbucket/bitbucket-sync-constants.ts b/backend/src/services/secret-sync/bitbucket/bitbucket-sync-constants.ts index 5d3f1274c..121d3910d 100644 --- a/backend/src/services/secret-sync/bitbucket/bitbucket-sync-constants.ts +++ b/backend/src/services/secret-sync/bitbucket/bitbucket-sync-constants.ts @@ -6,5 +6,5 @@ export const BITBUCKET_SYNC_LIST_OPTION: TSecretSyncListItem = { name: "Bitbucket", destination: SecretSync.Bitbucket, connection: AppConnection.Bitbucket, - canImportSecrets: true + 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 index d0a0df7a5..93b285c79 100644 --- a/backend/src/services/secret-sync/bitbucket/bitbucket-sync-fns.ts +++ b/backend/src/services/secret-sync/bitbucket/bitbucket-sync-fns.ts @@ -1,4 +1,5 @@ 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, @@ -11,29 +12,25 @@ 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"; -const createAuthHeader = (email: string, apiToken: string): string => { - return `Basic ${Buffer.from(`${email}:${apiToken}`).toString("base64")}`; -}; +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 ? `/${uuid}` : ""}`; + return `${baseUrl}/deployments_config/environments/${environment}/variables/${uuid || ""}`; } return `${baseUrl}/pipelines_config/variables/${uuid || ""}`; }; const listVariables = async ({ - email, - apiToken, - workspace, - repository, - environment -}: TBitbucketListVariables & { environment?: string }): Promise => { - const url = buildVariablesUrl(workspace, repository, environment); - const authHeader = createAuthHeader(email, apiToken); + workspaceSlug, + repositorySlug, + environmentId, + authHeader +}: TBitbucketListVariables): Promise => { + const url = buildVariablesUrl(workspaceSlug, repositorySlug, environmentId); const { data } = await request.get<{ values: TBitbucketVariable[] }>(url, { headers: { @@ -46,26 +43,23 @@ const listVariables = async ({ }; const upsertVariable = async ({ - email, - apiToken, - workspace, - repository, - environment, + workspaceSlug, + repositorySlug, + environmentId, key, value, - existingVariables + existingVariables, + authHeader }: { - email: string; - apiToken: string; - workspace: string; - repository: string; - environment?: string; + workspaceSlug: string; + repositorySlug: string; + environmentId?: string; key: string; value: string; existingVariables: TBitbucketVariable[]; + authHeader: string; }) => { const existingVariable = existingVariables.find((variable) => variable.key === key); - const authHeader = createAuthHeader(email, apiToken); const requestData = { key, value, secured: true }; const headers = { Authorization: authHeader, @@ -73,40 +67,37 @@ const upsertVariable = async ({ }; if (existingVariable) { - const url = buildVariablesUrl(workspace, repository, environment, existingVariable.uuid); + const url = buildVariablesUrl(workspaceSlug, repositorySlug, environmentId, existingVariable.uuid); return request.put(url, requestData, { headers }); } - const url = buildVariablesUrl(workspace, repository, environment); + const url = buildVariablesUrl(workspaceSlug, repositorySlug, environmentId); return request.post(url, requestData, { headers }); }; const putVariables = async ({ - email, - apiToken, - workspace, - repository, - environment, - secretMap -}: TPutBitbucketVariable & { environment?: string; secretMap: TSecretMap }) => { + workspaceSlug, + repositorySlug, + environmentId, + secretMap, + authHeader +}: TPutBitbucketVariable & { secretMap: TSecretMap; authHeader: string }) => { const existingVariables = await listVariables({ - email, - apiToken, - workspace, - repository, - environment + workspaceSlug, + repositorySlug, + environmentId, + authHeader }); const promises = Object.entries(secretMap).map(([key, { value }]) => upsertVariable({ - email, - apiToken, - workspace, - repository, - environment, + workspaceSlug, + repositorySlug, + environmentId, key, value, - existingVariables + existingVariables, + authHeader }) ); @@ -114,26 +105,22 @@ const putVariables = async ({ }; const deleteVariables = async ({ - email, - apiToken, - workspace, - repository, - environment, - keys -}: TDeleteBitbucketVariable & { environment?: string }) => { + workspaceSlug, + repositorySlug, + environmentId, + keys, + authHeader +}: TDeleteBitbucketVariable) => { const existingVariables = await listVariables({ - email, - apiToken, - workspace, - repository, - environment + workspaceSlug, + repositorySlug, + environmentId, + authHeader }); const variablesToDelete = existingVariables.filter((variable) => keys.includes(variable.key)); - - const authHeader = createAuthHeader(email, apiToken); const promises = variablesToDelete.map((variable) => { - const url = buildVariablesUrl(workspace, repository, environment, variable.uuid); + const url = buildVariablesUrl(workspaceSlug, repositorySlug, environmentId, variable.uuid); return request.delete(url, { headers: { Authorization: authHeader } }); @@ -147,19 +134,19 @@ export const BitbucketSyncFns = { const { connection, environment, - destinationConfig: { workspace, repository, environment: configEnvironment } + destinationConfig: { workspaceSlug, repositorySlug, environmentId } } = secretSync; const { email, apiToken } = connection.credentials; + const authHeader = createAuthHeader(email, apiToken); try { await putVariables({ - email, - apiToken, - workspace, - repository, - environment: configEnvironment, - secretMap + workspaceSlug, + repositorySlug, + environmentId, + secretMap, + authHeader }); } catch (error) { throw new SecretSyncError({ error }); @@ -169,11 +156,10 @@ export const BitbucketSyncFns = { try { const existingVariables = await listVariables({ - email, - apiToken, - workspace, - repository, - environment: configEnvironment + workspaceSlug, + repositorySlug, + environmentId, + authHeader }); const keysToDelete = existingVariables @@ -185,12 +171,11 @@ export const BitbucketSyncFns = { if (keysToDelete.length > 0) { await deleteVariables({ - email, - apiToken, - workspace, - repository, - environment: configEnvironment, - keys: keysToDelete + workspaceSlug, + repositorySlug, + environmentId, + keys: keysToDelete, + authHeader }); } } catch (error) { @@ -201,30 +186,29 @@ export const BitbucketSyncFns = { removeSecrets: async (secretSync: TBitbucketSyncWithCredentials, secretMap: TSecretMap) => { const { connection, - destinationConfig: { workspace, repository, environment: configEnvironment } + destinationConfig: { workspaceSlug, repositorySlug, environmentId } } = secretSync; const { email, apiToken } = connection.credentials; + const authHeader = createAuthHeader(email, apiToken); try { const existingVariables = await listVariables({ - email, - apiToken, - workspace, - repository, - environment: configEnvironment + workspaceSlug, + repositorySlug, + environmentId, + authHeader }); const keysToRemove = existingVariables.map((variable) => variable.key).filter((secret) => secret in secretMap); if (keysToRemove.length > 0) { await deleteVariables({ - email, - apiToken, - workspace, - repository, - environment: configEnvironment, - keys: keysToRemove + workspaceSlug, + repositorySlug, + environmentId, + keys: keysToRemove, + authHeader }); } } catch (error) { @@ -232,34 +216,7 @@ export const BitbucketSyncFns = { } }, - getSecrets: async (secretSync: TBitbucketSyncWithCredentials) => { - const { - connection, - destinationConfig: { workspace, repository, environment } - } = secretSync; - - const { email, apiToken } = connection.credentials; - - try { - const variables = await listVariables({ - email, - apiToken, - workspace, - repository, - environment - }); - - const secretMap: TSecretMap = {}; - variables.forEach((variable) => { - secretMap[variable.key] = { - value: variable.secured ? "[SECURED]" : variable.value || "", - comment: "" - }; - }); - - return secretMap; - } 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 index d5df5fb3a..985d86e8d 100644 --- a/backend/src/services/secret-sync/bitbucket/bitbucket-sync-schemas.ts +++ b/backend/src/services/secret-sync/bitbucket/bitbucket-sync-schemas.ts @@ -11,12 +11,12 @@ import { import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; const BitbucketSyncDestinationConfigSchema = z.object({ - repository: z.string().describe(SecretSyncs.DESTINATION_CONFIG.BITBUCKET.repository), - environment: z.string().optional().describe(SecretSyncs.DESTINATION_CONFIG.BITBUCKET.environment), - workspace: z.string().describe(SecretSyncs.DESTINATION_CONFIG.BITBUCKET.workspace) + 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: true }; +const BitbucketSyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false }; export const BitbucketSyncSchema = BaseSecretSyncSchema(SecretSync.Bitbucket, BitbucketSyncOptionsConfig).extend({ destination: z.literal(SecretSync.Bitbucket), @@ -41,5 +41,5 @@ export const BitbucketSyncListItemSchema = z.object({ name: z.literal("Bitbucket"), connection: z.literal(AppConnection.Bitbucket), destination: z.literal(SecretSync.Bitbucket), - canImportSecrets: z.literal(true) + 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 index b8ff85f30..a28e27487 100644 --- a/backend/src/services/secret-sync/bitbucket/bitbucket-sync-types.ts +++ b/backend/src/services/secret-sync/bitbucket/bitbucket-sync-types.ts @@ -17,34 +17,34 @@ export type TBitbucketSyncWithCredentials = TBitbucketSync & { 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 = { - apiToken: string; - email: string; - workspace: string; - repository: string; + workspaceSlug: string; + repositorySlug: string; + environmentId?: string; + authHeader: string; }; export type TPutBitbucketVariable = { - email: string; - apiToken: string; - workspace: string; - repository: string; + authHeader: string; + workspaceSlug: string; + repositorySlug: string; + environmentId?: string; }; export type TDeleteBitbucketVariable = { - email: string; - apiToken: string; - workspace: string; - repository: string; + authHeader: string; + workspaceSlug: string; + repositorySlug: string; + environmentId?: string; keys: string[]; }; export type TBitbucketConnectionCredentials = { - email: string; - apiToken: string; + authHeader: string; }; 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/secret-syncs/bitbucket/configure-sync-options.png b/docs/images/secret-syncs/bitbucket/configure-sync-options.png index 9afbaaafe..471b2851c 100644 Binary files a/docs/images/secret-syncs/bitbucket/configure-sync-options.png and b/docs/images/secret-syncs/bitbucket/configure-sync-options.png differ diff --git a/docs/integrations/app-connections/bitbucket.mdx b/docs/integrations/app-connections/bitbucket.mdx index 20923122e..be4fdbee7 100644 --- a/docs/integrations/app-connections/bitbucket.mdx +++ b/docs/integrations/app-connections/bitbucket.mdx @@ -50,13 +50,15 @@ 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:workspace:bitbucket admin:pipeline:bitbucket ``` + + ![Configure Permissions](/images/app-connections/bitbucket/step-4-secret-sync.png) diff --git a/docs/integrations/secret-syncs/bitbucket.mdx b/docs/integrations/secret-syncs/bitbucket.mdx index f05f5d822..9793e89c9 100644 --- a/docs/integrations/secret-syncs/bitbucket.mdx +++ b/docs/integrations/secret-syncs/bitbucket.mdx @@ -46,8 +46,9 @@ description: "Learn how to configure a Bitbucket Sync for Infisical." - **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. - - **Import Secrets (Prioritize Infisical)**: Imports secrets from the destination endpoint before syncing, prioritizing values from Infisical over Bitbucket when keys conflict. - - **Import Secrets (Prioritize Bitbucket)**: Imports secrets from the destination endpoint before syncing, prioritizing values from Bitbucket over Infisical when keys conflict. + + 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. @@ -96,8 +97,8 @@ description: "Learn how to configure a Bitbucket Sync for Infisical." "initialSyncBehavior": "overwrite-destination" }, "destinationConfig": { - "workspace": "my-bitbucket-workspace", - "repository": "my-bitbucket-repository" + "workspaceSlug": "my-bitbucket-workspace", + "repositorySlug": "my-bitbucket-repository" } }' ``` @@ -148,8 +149,8 @@ description: "Learn how to configure a Bitbucket Sync for Infisical." }, "destination": "bitbucket", "destinationConfig": { - "workspace": "my-bitbucket-workspace", - "repository": "my-bitbucket-repository" + "workspaceSlug": "my-bitbucket-workspace", + "repositorySlug": "my-bitbucket-repository" } } } diff --git a/frontend/src/components/secret-syncs/forms/SecretSyncDestinationFields/BitbucketSyncFields.tsx b/frontend/src/components/secret-syncs/forms/SecretSyncDestinationFields/BitbucketSyncFields.tsx index 2cf5a541f..330d75811 100644 --- a/frontend/src/components/secret-syncs/forms/SecretSyncDestinationFields/BitbucketSyncFields.tsx +++ b/frontend/src/components/secret-syncs/forms/SecretSyncDestinationFields/BitbucketSyncFields.tsx @@ -21,8 +21,8 @@ export const BitbucketSyncFields = () => { >(); const connectionId = useWatch({ name: "connection.id", control }); - const workspace = useWatch({ name: "destinationConfig.workspace", control }); - const repository = useWatch({ name: "destinationConfig.repository", control }); + const workspace = useWatch({ name: "destinationConfig.workspaceSlug", control }); + const repository = useWatch({ name: "destinationConfig.repositorySlug", control }); const { data: workspaces = [], isPending: isWorkspacesLoading } = useBitbucketConnectionListWorkspaces(connectionId, { @@ -43,14 +43,14 @@ export const BitbucketSyncFields = () => { <> { - setValue("destinationConfig.workspace", ""); - setValue("destinationConfig.repository", ""); - setValue("destinationConfig.environment", ""); + setValue("destinationConfig.workspaceSlug", ""); + setValue("destinationConfig.repositorySlug", ""); + setValue("destinationConfig.environmentId", ""); }} /> ( { const v = option as SingleValue; onChange(v?.slug ?? ""); // Clear downstream selections - setValue("destinationConfig.repository", ""); - setValue("destinationConfig.environment", ""); + setValue("destinationConfig.repositorySlug", ""); + setValue("destinationConfig.environmentId", ""); }} options={workspaces} placeholder="Select workspace..." @@ -80,7 +80,7 @@ export const BitbucketSyncFields = () => { /> ( { const v = option as SingleValue; onChange(v?.slug ?? ""); // Clear downstream selections - setValue("destinationConfig.environment", ""); + setValue("destinationConfig.environmentId", ""); }} options={repositories} placeholder="Select repository..." @@ -109,13 +109,14 @@ export const BitbucketSyncFields = () => { /> ( { const { watch } = useFormContext(); - const repository = watch("destinationConfig.repository"); - const environment = watch("destinationConfig.environment"); - const workspace = watch("destinationConfig.workspace"); + const repository = watch("destinationConfig.repositorySlug"); + const environment = watch("destinationConfig.environmentId"); + const workspace = watch("destinationConfig.workspaceSlug"); return ( <> 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 index 352e36f24..a10a22d5a 100644 --- 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 @@ -7,9 +7,13 @@ export const BitbucketSyncDestinationSchema = BaseSecretSyncSchema().merge( z.object({ destination: z.literal(SecretSync.Bitbucket), destinationConfig: z.object({ - repository: z.string().trim().min(1, "Repository slug required").describe("Repository slug"), - environment: z.string().trim().optional().describe("Deployment environment uuid"), - workspace: z.string().trim().min(1, "Workspace slug required").describe("Workspace slug") + 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/hooks/api/secretSyncs/types/bitbucket-sync.ts b/frontend/src/hooks/api/secretSyncs/types/bitbucket-sync.ts index 17bd2be05..829b96da3 100644 --- a/frontend/src/hooks/api/secretSyncs/types/bitbucket-sync.ts +++ b/frontend/src/hooks/api/secretSyncs/types/bitbucket-sync.ts @@ -5,9 +5,9 @@ import { TRootSecretSync } from "@app/hooks/api/secretSyncs/types/root-sync"; export type TBitbucketSync = TRootSecretSync & { destination: SecretSync.Bitbucket; destinationConfig: { - workspace: string; - repository: string; - environment?: string; + workspaceSlug: string; + repositorySlug: string; + environmentId?: string; }; connection: { app: AppConnection.Bitbucket; 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 364efaaab..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 @@ -175,8 +175,8 @@ export const getSecretSyncDestinationColValues = (secretSync: TSecretSync) => { secondaryText = "Supabase Project"; break; case SecretSync.Bitbucket: - primaryText = destinationConfig.workspace; - secondaryText = destinationConfig.repository; + primaryText = destinationConfig.workspaceSlug; + secondaryText = destinationConfig.repositorySlug; break; default: throw new Error(`Unhandled Destination Col Values ${destination}`); diff --git a/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncDestinationSection/BitbucketSyncDestinationSection.tsx b/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncDestinationSection/BitbucketSyncDestinationSection.tsx index eb5378f2f..04999b969 100644 --- a/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncDestinationSection/BitbucketSyncDestinationSection.tsx +++ b/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncDestinationSection/BitbucketSyncDestinationSection.tsx @@ -7,15 +7,15 @@ type Props = { export const BitbucketSyncDestinationSection = ({ secretSync }: Props) => { const { - destinationConfig: { workspace, repository, environment } + destinationConfig: { workspaceSlug, repositorySlug, environmentId } } = secretSync; return ( <> - {workspace} - {repository} - {environment && ( - {environment} + {workspaceSlug} + {repositorySlug} + {environmentId && ( + {environmentId} )} );