Merge pull request #4210 from Infisical/feat/bitbucketSecretSync

Add Bitbucket Secret Sync
This commit is contained in:
carlosmonastyrski
2025-07-23 11:07:07 -03:00
committed by GitHub
56 changed files with 1047 additions and 24 deletions

View File

@@ -2506,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."
}
}
};

View File

@@ -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 };
}
});
};

View File

@@ -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
});

View File

@@ -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<SecretSync, (server: Fastif
[SecretSync.Supabase]: registerSupabaseSyncRouter,
[SecretSync.Zabbix]: registerZabbixSyncRouter,
[SecretSync.Railway]: registerRailwaySyncRouter,
[SecretSync.Checkly]: registerChecklySyncRouter
[SecretSync.Checkly]: registerChecklySyncRouter,
[SecretSync.Bitbucket]: registerBitbucketSyncRouter
};

View File

@@ -21,6 +21,7 @@ import {
} from "@app/services/secret-sync/azure-app-configuration";
import { AzureDevOpsSyncListItemSchema, AzureDevOpsSyncSchema } from "@app/services/secret-sync/azure-devops";
import { AzureKeyVaultSyncListItemSchema, AzureKeyVaultSyncSchema } from "@app/services/secret-sync/azure-key-vault";
import { BitbucketSyncListItemSchema, BitbucketSyncSchema } from "@app/services/secret-sync/bitbucket";
import { CamundaSyncListItemSchema, CamundaSyncSchema } from "@app/services/secret-sync/camunda";
import { ChecklySyncListItemSchema, ChecklySyncSchema } from "@app/services/secret-sync/checkly/checkly-sync-schemas";
import {
@@ -75,7 +76,8 @@ const SecretSyncSchema = z.discriminatedUnion("destination", [
SupabaseSyncSchema,
ZabbixSyncSchema,
RailwaySyncSchema,
ChecklySyncSchema
ChecklySyncSchema,
BitbucketSyncSchema
]);
const SecretSyncOptionsSchema = z.discriminatedUnion("destination", [
@@ -102,11 +104,11 @@ const SecretSyncOptionsSchema = z.discriminatedUnion("destination", [
GitLabSyncListItemSchema,
CloudflarePagesSyncListItemSchema,
CloudflareWorkersSyncListItemSchema,
ZabbixSyncListItemSchema,
RailwaySyncListItemSchema,
ChecklySyncListItemSchema,
SupabaseSyncListItemSchema
SupabaseSyncListItemSchema,
BitbucketSyncListItemSchema
]);
export const registerSecretSyncRouter = async (server: FastifyZodProvider) => {

View File

@@ -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;
};

View File

@@ -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
};
};

View File

@@ -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;
};

View File

@@ -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
};

View File

@@ -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<TBitbucketVariable[]> => {
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<TSecretMap> => {
throw new Error(`${SECRET_SYNC_NAME_MAP[secretSync.destination]} does not support importing secrets.`);
}
};

View File

@@ -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)
});

View File

@@ -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<typeof BitbucketSyncSchema>;
export type TBitbucketSyncInput = z.infer<typeof CreateBitbucketSyncSchema>;
export type TBitbucketSyncListItem = z.infer<typeof BitbucketSyncListItemSchema>;
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;
};

View File

@@ -0,0 +1,4 @@
export * from "./bitbucket-sync-constants";
export * from "./bitbucket-sync-fns";
export * from "./bitbucket-sync-schemas";
export * from "./bitbucket-sync-types";

View File

@@ -25,7 +25,8 @@ export enum SecretSync {
Supabase = "supabase",
Zabbix = "zabbix",
Railway = "railway",
Checkly = "checkly"
Checkly = "checkly",
Bitbucket = "bitbucket"
}
export enum SecretSyncInitialSyncBehavior {

View File

@@ -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, TSecretSyncListItem> = {
[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}`

View File

@@ -28,7 +28,8 @@ export const SECRET_SYNC_NAME_MAP: Record<SecretSync, string> = {
[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<SecretSync, AppConnection> = {
@@ -58,7 +59,8 @@ export const SECRET_SYNC_CONNECTION_MAP: Record<SecretSync, AppConnection> = {
[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<SecretSync, SecretSyncPlanType> = {
@@ -88,5 +90,6 @@ export const SECRET_SYNC_PLAN_MAP: Record<SecretSync, SecretSyncPlanType> = {
[SecretSync.Supabase]: SecretSyncPlanType.Regular,
[SecretSync.Zabbix]: SecretSyncPlanType.Regular,
[SecretSync.Railway]: SecretSyncPlanType.Regular,
[SecretSync.Checkly]: SecretSyncPlanType.Regular
[SecretSync.Checkly]: SecretSyncPlanType.Regular,
[SecretSync.Bitbucket]: SecretSyncPlanType.Regular
};

View File

@@ -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;