mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-14 09:30:09 +00:00
Make webhooks work, add workspace selection, rename BitBucket to
Bitbucket
This commit is contained in:
+65
-12
@@ -1,13 +1,15 @@
|
||||
import { useEffect } from "react";
|
||||
import { Controller, useFormContext, useWatch } from "react-hook-form";
|
||||
import { MultiValue } from "react-select";
|
||||
import { MultiValue, SingleValue } from "react-select";
|
||||
import { faCircleInfo } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
import { FilterableSelect, FormControl, Select, SelectItem, Tooltip } from "@app/components/v2";
|
||||
import {
|
||||
TBitBucketRepo,
|
||||
useBitBucketConnectionListRepositories
|
||||
TBitbucketRepo,
|
||||
TBitbucketWorkspace,
|
||||
useBitbucketConnectionListRepositories,
|
||||
useBitbucketConnectionListWorkspaces
|
||||
} from "@app/hooks/api/appConnections/bitbucket";
|
||||
import { SecretScanningDataSource } from "@app/hooks/api/secretScanningV2";
|
||||
|
||||
@@ -19,18 +21,25 @@ enum ScanMethod {
|
||||
SelectRepositories = "select-repositories"
|
||||
}
|
||||
|
||||
export const BitBucketDataSourceConfigFields = () => {
|
||||
export const BitbucketDataSourceConfigFields = () => {
|
||||
const { control, watch, setValue } = useFormContext<
|
||||
TSecretScanningDataSourceForm & {
|
||||
type: SecretScanningDataSource.BitBucket;
|
||||
type: SecretScanningDataSource.Bitbucket;
|
||||
}
|
||||
>();
|
||||
|
||||
const connectionId = useWatch({ control, name: "connection.id" });
|
||||
const isUpdate = Boolean(watch("id"));
|
||||
|
||||
const selectedWorkspaceSlug = useWatch({ control, name: "config.workspaceSlug" });
|
||||
|
||||
const { data: workspaces, isPending: areWorkspacesLoading } =
|
||||
useBitbucketConnectionListWorkspaces(connectionId, { enabled: Boolean(connectionId) });
|
||||
|
||||
const { data: repositories, isPending: areRepositoriesLoading } =
|
||||
useBitBucketConnectionListRepositories(connectionId, { enabled: Boolean(connectionId) });
|
||||
useBitbucketConnectionListRepositories(connectionId, selectedWorkspaceSlug, {
|
||||
enabled: Boolean(connectionId) && Boolean(selectedWorkspaceSlug) // Enable only if both are present
|
||||
});
|
||||
|
||||
const includeRepos = watch("config.includeRepos");
|
||||
|
||||
@@ -51,10 +60,50 @@ export const BitBucketDataSourceConfigFields = () => {
|
||||
isUpdate={isUpdate}
|
||||
onChange={() => {
|
||||
if (scanMethod === ScanMethod.SelectRepositories) {
|
||||
setValue("config.workspaceSlug", "");
|
||||
setValue("config.includeRepos", []);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Controller
|
||||
name="config.workspaceSlug"
|
||||
control={control}
|
||||
render={({ field: { value, onChange }, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
label="Workspace"
|
||||
helperText={
|
||||
<Tooltip
|
||||
className="max-w-md"
|
||||
content={<>Ensure that your connection has the correct permissions.</>}
|
||||
>
|
||||
<div>
|
||||
<span>Don't see the workspaces you're looking for?</span>{" "}
|
||||
<FontAwesomeIcon icon={faCircleInfo} className="text-mineshaft-400" />
|
||||
</div>
|
||||
</Tooltip>
|
||||
}
|
||||
>
|
||||
<FilterableSelect
|
||||
menuPlacement="top"
|
||||
isLoading={areWorkspacesLoading && Boolean(connectionId)}
|
||||
isDisabled={!connectionId}
|
||||
value={value ? { slug: value } : null}
|
||||
onChange={(newValue) => {
|
||||
onChange((newValue as SingleValue<TBitbucketWorkspace>)?.slug);
|
||||
if (scanMethod === ScanMethod.SelectRepositories) {
|
||||
setValue("config.includeRepos", []);
|
||||
}
|
||||
}}
|
||||
options={workspaces}
|
||||
placeholder="Select workspace..."
|
||||
getOptionLabel={(option) => option.slug}
|
||||
getOptionValue={(option) => option.slug}
|
||||
/>
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
<FormControl label="Scan Repositories">
|
||||
<Select
|
||||
value={scanMethod}
|
||||
@@ -78,7 +127,7 @@ export const BitBucketDataSourceConfigFields = () => {
|
||||
{scanMethod === ScanMethod.SelectRepositories && (
|
||||
<Controller
|
||||
name="config.includeRepos"
|
||||
defaultValue={["*"]}
|
||||
// defaultValue={["*"]} // This defaultValue is handled by the useEffect above
|
||||
control={control}
|
||||
render={({ field: { value, onChange }, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
@@ -100,18 +149,22 @@ export const BitBucketDataSourceConfigFields = () => {
|
||||
<FilterableSelect
|
||||
menuPlacement="top"
|
||||
isLoading={areRepositoriesLoading && Boolean(connectionId)}
|
||||
isDisabled={!connectionId}
|
||||
// Disable if no connection or no workspace slug is selected for fetching repositories
|
||||
isDisabled={!connectionId || !selectedWorkspaceSlug}
|
||||
isMulti
|
||||
value={repositories?.filter((repository) => value.includes(repository.name))}
|
||||
// Ensure 'value' is treated as a string array for filtering
|
||||
value={repositories?.filter((repository) =>
|
||||
(value as string[]).includes(repository.full_name)
|
||||
)}
|
||||
onChange={(newValue) => {
|
||||
onChange(
|
||||
newValue ? (newValue as MultiValue<TBitBucketRepo>).map((p) => p.name) : null
|
||||
newValue ? (newValue as MultiValue<TBitbucketRepo>).map((p) => p.full_name) : [] // Ensure it's an empty array if cleared
|
||||
);
|
||||
}}
|
||||
options={repositories}
|
||||
placeholder="Select repositories..."
|
||||
getOptionLabel={(option) => option.name}
|
||||
getOptionValue={(option) => option.name}
|
||||
getOptionLabel={(option) => option.full_name}
|
||||
getOptionValue={(option) => option.full_name}
|
||||
/>
|
||||
</FormControl>
|
||||
)}
|
||||
|
||||
+2
-2
@@ -5,12 +5,12 @@ import { RESOURCE_DESCRIPTION_HELPER } from "@app/helpers/secretScanningV2";
|
||||
import { SecretScanningDataSource } from "@app/hooks/api/secretScanningV2";
|
||||
|
||||
import { TSecretScanningDataSourceForm } from "../schemas";
|
||||
import { BitBucketDataSourceConfigFields } from "./BitBucketDataSourceConfigFields";
|
||||
import { BitbucketDataSourceConfigFields } from "./BitbucketDataSourceConfigFields";
|
||||
import { GitHubDataSourceConfigFields } from "./GitHubDataSourceConfigFields";
|
||||
|
||||
const COMPONENT_MAP: Record<SecretScanningDataSource, React.FC> = {
|
||||
[SecretScanningDataSource.GitHub]: GitHubDataSourceConfigFields,
|
||||
[SecretScanningDataSource.BitBucket]: BitBucketDataSourceConfigFields
|
||||
[SecretScanningDataSource.Bitbucket]: BitbucketDataSourceConfigFields
|
||||
};
|
||||
|
||||
export const SecretScanningDataSourceConfigFields = () => {
|
||||
|
||||
+2
-2
@@ -6,10 +6,10 @@ import { SecretScanningDataSource } from "@app/hooks/api/secretScanningV2";
|
||||
import { TSecretScanningDataSourceForm } from "../schemas";
|
||||
import { SecretScanningDataSourceConfigReviewSection } from "./shared";
|
||||
|
||||
export const BitBucketDataSourceReviewFields = () => {
|
||||
export const BitbucketDataSourceReviewFields = () => {
|
||||
const { watch } = useFormContext<
|
||||
TSecretScanningDataSourceForm & {
|
||||
type: SecretScanningDataSource.BitBucket;
|
||||
type: SecretScanningDataSource.Bitbucket;
|
||||
}
|
||||
>();
|
||||
|
||||
|
||||
+2
-2
@@ -4,12 +4,12 @@ import { GenericFieldLabel } from "@app/components/v2";
|
||||
import { SecretScanningDataSource } from "@app/hooks/api/secretScanningV2";
|
||||
|
||||
import { TSecretScanningDataSourceForm } from "../schemas";
|
||||
import { BitBucketDataSourceReviewFields } from "./BitBucketDataSourceReviewFields";
|
||||
import { BitbucketDataSourceReviewFields } from "./BitbucketDataSourceReviewFields";
|
||||
import { GitHubDataSourceReviewFields } from "./GitHubDataSourceReviewFields";
|
||||
|
||||
const COMPONENT_MAP: Record<SecretScanningDataSource, React.FC> = {
|
||||
[SecretScanningDataSource.GitHub]: GitHubDataSourceReviewFields,
|
||||
[SecretScanningDataSource.BitBucket]: BitBucketDataSourceReviewFields
|
||||
[SecretScanningDataSource.Bitbucket]: BitbucketDataSourceReviewFields
|
||||
};
|
||||
|
||||
export const SecretScanningDataSourceReviewFields = () => {
|
||||
|
||||
+3
-2
@@ -4,10 +4,11 @@ import { SecretScanningDataSource } from "@app/hooks/api/secretScanningV2";
|
||||
|
||||
import { BaseSecretScanningDataSourceSchema } from "./base-secret-scanning-data-source-schema";
|
||||
|
||||
export const BitBucketDataSourceSchema = z
|
||||
export const BitbucketDataSourceSchema = z
|
||||
.object({
|
||||
type: z.literal(SecretScanningDataSource.BitBucket),
|
||||
type: z.literal(SecretScanningDataSource.Bitbucket),
|
||||
config: z.object({
|
||||
workspaceSlug: z.string().min(1, "Workspace Required").max(128),
|
||||
includeRepos: z
|
||||
.string()
|
||||
.array()
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { BitBucketDataSourceSchema } from "./bitbucket-data-source-schema";
|
||||
import { BitbucketDataSourceSchema } from "./bitbucket-data-source-schema";
|
||||
import { GitHubDataSourceSchema } from "./github-data-source-schema";
|
||||
|
||||
export const SecretScanningDataSourceSchema = z.discriminatedUnion("type", [
|
||||
GitHubDataSourceSchema,
|
||||
BitBucketDataSourceSchema
|
||||
BitbucketDataSourceSchema
|
||||
]);
|
||||
|
||||
export type TSecretScanningDataSourceForm = z.infer<typeof SecretScanningDataSourceSchema>;
|
||||
|
||||
@@ -39,7 +39,7 @@ import {
|
||||
VercelConnectionMethod,
|
||||
WindmillConnectionMethod
|
||||
} from "@app/hooks/api/appConnections/types";
|
||||
import { BitBucketConnectionMethod } from "@app/hooks/api/appConnections/types/bitbucket-connection";
|
||||
import { BitbucketConnectionMethod } from "@app/hooks/api/appConnections/types/bitbucket-connection";
|
||||
import { HerokuConnectionMethod } from "@app/hooks/api/appConnections/types/heroku-connection";
|
||||
import { OCIConnectionMethod } from "@app/hooks/api/appConnections/types/oci-connection";
|
||||
import { RenderConnectionMethod } from "@app/hooks/api/appConnections/types/render-connection";
|
||||
@@ -90,7 +90,7 @@ export const APP_CONNECTION_MAP: Record<
|
||||
[AppConnection.Flyio]: { name: "Fly.io", image: "Flyio.svg" },
|
||||
[AppConnection.Gitlab]: { name: "GitLab", image: "GitLab.png" },
|
||||
[AppConnection.Cloudflare]: { name: "Cloudflare", image: "Cloudflare.png" },
|
||||
[AppConnection.BitBucket]: { name: "BitBucket", image: "BitBucket.png" }
|
||||
[AppConnection.Bitbucket]: { name: "Bitbucket", image: "Bitbucket.png" }
|
||||
};
|
||||
|
||||
export const getAppConnectionMethodDetails = (method: TAppConnection["method"]) => {
|
||||
@@ -122,7 +122,7 @@ export const getAppConnectionMethodDetails = (method: TAppConnection["method"])
|
||||
case VercelConnectionMethod.ApiToken:
|
||||
case OnePassConnectionMethod.ApiToken:
|
||||
case CloudflareConnectionMethod.ApiToken:
|
||||
case BitBucketConnectionMethod.ApiToken:
|
||||
case BitbucketConnectionMethod.ApiToken:
|
||||
return { name: "API Token", icon: faKey };
|
||||
case PostgresConnectionMethod.UsernameAndPassword:
|
||||
case MsSqlConnectionMethod.UsernameAndPassword:
|
||||
|
||||
@@ -20,9 +20,9 @@ export const SECRET_SCANNING_DATA_SOURCE_MAP: Record<
|
||||
image: "GitHub.png",
|
||||
size: 45
|
||||
},
|
||||
[SecretScanningDataSource.BitBucket]: {
|
||||
name: "BitBucket",
|
||||
image: "BitBucket.png",
|
||||
[SecretScanningDataSource.Bitbucket]: {
|
||||
name: "Bitbucket",
|
||||
image: "Bitbucket.png",
|
||||
size: 45
|
||||
}
|
||||
};
|
||||
@@ -32,7 +32,7 @@ export const SECRET_SCANNING_DATA_SOURCE_CONNECTION_MAP: Record<
|
||||
AppConnection
|
||||
> = {
|
||||
[SecretScanningDataSource.GitHub]: AppConnection.GitHubRadar,
|
||||
[SecretScanningDataSource.BitBucket]: AppConnection.BitBucket
|
||||
[SecretScanningDataSource.Bitbucket]: AppConnection.Bitbucket
|
||||
};
|
||||
|
||||
export const RESOURCE_DESCRIPTION_HELPER: Record<
|
||||
@@ -52,7 +52,7 @@ export const RESOURCE_DESCRIPTION_HELPER: Record<
|
||||
pluralTitle: "Repositories",
|
||||
singularTitle: "Repository"
|
||||
},
|
||||
[SecretScanningDataSource.BitBucket]: {
|
||||
[SecretScanningDataSource.Bitbucket]: {
|
||||
verb: "push",
|
||||
pluralNoun: "repositories",
|
||||
singularNoun: "repository",
|
||||
|
||||
@@ -3,31 +3,67 @@ import { useQuery, UseQueryOptions } from "@tanstack/react-query";
|
||||
import { apiRequest } from "@app/config/request";
|
||||
|
||||
import { appConnectionKeys } from "../queries";
|
||||
import { TBitBucketConnectionListRepositoriesResponse, TBitBucketRepo } from "./types";
|
||||
import {
|
||||
TBitbucketConnectionListRepositoriesResponse,
|
||||
TBitbucketConnectionListWorkspacesResponse,
|
||||
TBitbucketRepo,
|
||||
TBitbucketWorkspace
|
||||
} from "./types";
|
||||
|
||||
const bitBucketConnectionKeys = {
|
||||
all: [...appConnectionKeys.all, "bitbucket"] as const,
|
||||
listRepos: (connectionId: string) =>
|
||||
[...bitBucketConnectionKeys.all, "repos", connectionId] as const
|
||||
listRepos: (connectionId: string, workspaceSlug: string) =>
|
||||
[...bitBucketConnectionKeys.all, "repos", connectionId, workspaceSlug] as const,
|
||||
listWorkspaces: (connectionId: string) =>
|
||||
[...bitBucketConnectionKeys.all, "workspaces", connectionId] as const
|
||||
};
|
||||
|
||||
export const useBitBucketConnectionListRepositories = (
|
||||
export const useBitbucketConnectionListWorkspaces = (
|
||||
connectionId: string,
|
||||
options?: Omit<
|
||||
UseQueryOptions<
|
||||
TBitBucketRepo[],
|
||||
TBitbucketWorkspace[],
|
||||
unknown,
|
||||
TBitBucketRepo[],
|
||||
TBitbucketWorkspace[],
|
||||
ReturnType<typeof bitBucketConnectionKeys.listWorkspaces>
|
||||
>,
|
||||
"queryKey" | "queryFn"
|
||||
>
|
||||
) => {
|
||||
return useQuery({
|
||||
queryKey: bitBucketConnectionKeys.listWorkspaces(connectionId),
|
||||
queryFn: async () => {
|
||||
const { data } = await apiRequest.get<TBitbucketConnectionListWorkspacesResponse>(
|
||||
`/api/v1/app-connections/bitbucket/${connectionId}/workspaces`
|
||||
);
|
||||
|
||||
return data.workspaces;
|
||||
},
|
||||
...options
|
||||
});
|
||||
};
|
||||
|
||||
export const useBitbucketConnectionListRepositories = (
|
||||
connectionId: string,
|
||||
workspaceSlug: string,
|
||||
options?: Omit<
|
||||
UseQueryOptions<
|
||||
TBitbucketRepo[],
|
||||
unknown,
|
||||
TBitbucketRepo[],
|
||||
// The ReturnType here will be a supertype of the actual queryKey, which is acceptable
|
||||
ReturnType<typeof bitBucketConnectionKeys.listRepos>
|
||||
>,
|
||||
"queryKey" | "queryFn"
|
||||
>
|
||||
) => {
|
||||
return useQuery({
|
||||
queryKey: bitBucketConnectionKeys.listRepos(connectionId),
|
||||
// Append workspaceSlug to the existing query key for unique caching
|
||||
queryKey: bitBucketConnectionKeys.listRepos(connectionId, workspaceSlug),
|
||||
queryFn: async () => {
|
||||
const { data } = await apiRequest.get<TBitBucketConnectionListRepositoriesResponse>(
|
||||
`/api/v1/app-connections/bitbucket/${connectionId}/repositories`
|
||||
const { data } = await apiRequest.get<TBitbucketConnectionListRepositoriesResponse>(
|
||||
// Include workspaceSlug in the API endpoint path
|
||||
`/api/v1/app-connections/bitbucket/${connectionId}/repositories?workspaceSlug=${workspaceSlug}`
|
||||
);
|
||||
|
||||
return data.repositories;
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
export type TBitBucketRepo = {
|
||||
id: string;
|
||||
name: string; // workspace-slug/repo-slug
|
||||
export type TBitbucketWorkspace = {
|
||||
slug: string;
|
||||
};
|
||||
|
||||
export type TBitBucketConnectionListRepositoriesResponse = {
|
||||
repositories: TBitBucketRepo[];
|
||||
export type TBitbucketRepo = {
|
||||
slug: string;
|
||||
full_name: string; // workspace-slug/repo-slug
|
||||
};
|
||||
|
||||
export type TBitbucketConnectionListWorkspacesResponse = {
|
||||
workspaces: TBitbucketWorkspace[];
|
||||
};
|
||||
|
||||
export type TBitbucketConnectionListRepositoriesResponse = {
|
||||
repositories: TBitbucketRepo[];
|
||||
};
|
||||
|
||||
@@ -28,5 +28,5 @@ export enum AppConnection {
|
||||
Flyio = "flyio",
|
||||
Gitlab = "gitlab",
|
||||
Cloudflare = "cloudflare",
|
||||
BitBucket = "bitbucket"
|
||||
Bitbucket = "bitbucket"
|
||||
}
|
||||
|
||||
@@ -132,8 +132,8 @@ export type TCloudflareConnectionOption = TAppConnectionOptionBase & {
|
||||
app: AppConnection.Cloudflare;
|
||||
};
|
||||
|
||||
export type TBitBucketConnectionOption = TAppConnectionOptionBase & {
|
||||
app: AppConnection.BitBucket;
|
||||
export type TBitbucketConnectionOption = TAppConnectionOptionBase & {
|
||||
app: AppConnection.Bitbucket;
|
||||
};
|
||||
|
||||
export type TAppConnectionOption =
|
||||
@@ -164,7 +164,7 @@ export type TAppConnectionOption =
|
||||
| TFlyioConnectionOption
|
||||
| TGitlabConnectionOption
|
||||
| TCloudflareConnectionOption
|
||||
| TBitBucketConnectionOption;
|
||||
| TBitbucketConnectionOption;
|
||||
|
||||
export type TAppConnectionOptionMap = {
|
||||
[AppConnection.AWS]: TAwsConnectionOption;
|
||||
@@ -196,5 +196,5 @@ export type TAppConnectionOptionMap = {
|
||||
[AppConnection.Flyio]: TFlyioConnectionOption;
|
||||
[AppConnection.Gitlab]: TGitlabConnectionOption;
|
||||
[AppConnection.Cloudflare]: TCloudflareConnectionOption;
|
||||
[AppConnection.BitBucket]: TBitBucketConnectionOption;
|
||||
[AppConnection.Bitbucket]: TBitbucketConnectionOption;
|
||||
};
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { AppConnection } from "@app/hooks/api/appConnections/enums";
|
||||
import { TRootAppConnection } from "@app/hooks/api/appConnections/types/root-connection";
|
||||
|
||||
export enum BitBucketConnectionMethod {
|
||||
export enum BitbucketConnectionMethod {
|
||||
ApiToken = "api-token"
|
||||
}
|
||||
|
||||
export type TBitBucketConnection = TRootAppConnection & { app: AppConnection.BitBucket } & {
|
||||
method: BitBucketConnectionMethod.ApiToken;
|
||||
export type TBitbucketConnection = TRootAppConnection & { app: AppConnection.Bitbucket } & {
|
||||
method: BitbucketConnectionMethod.ApiToken;
|
||||
credentials: {
|
||||
email: string;
|
||||
apiToken: string;
|
||||
|
||||
@@ -7,7 +7,7 @@ import { TAzureAppConfigurationConnection } from "./azure-app-configuration-conn
|
||||
import { TAzureClientSecretsConnection } from "./azure-client-secrets-connection";
|
||||
import { TAzureDevOpsConnection } from "./azure-devops-connection";
|
||||
import { TAzureKeyVaultConnection } from "./azure-key-vault-connection";
|
||||
import { TBitBucketConnection } from "./bitbucket-connection";
|
||||
import { TBitbucketConnection } from "./bitbucket-connection";
|
||||
import { TCamundaConnection } from "./camunda-connection";
|
||||
import { TCloudflareConnection } from "./cloudflare-connection";
|
||||
import { TDatabricksConnection } from "./databricks-connection";
|
||||
@@ -92,7 +92,7 @@ export type TAppConnection =
|
||||
| TFlyioConnection
|
||||
| TGitLabConnection
|
||||
| TCloudflareConnection
|
||||
| TBitBucketConnection;
|
||||
| TBitbucketConnection;
|
||||
|
||||
export type TAvailableAppConnection = Pick<TAppConnection, "name" | "id">;
|
||||
|
||||
@@ -149,5 +149,5 @@ export type TAppConnectionMap = {
|
||||
[AppConnection.Flyio]: TFlyioConnection;
|
||||
[AppConnection.Gitlab]: TGitLabConnection;
|
||||
[AppConnection.Cloudflare]: TCloudflareConnection;
|
||||
[AppConnection.BitBucket]: TBitBucketConnection;
|
||||
[AppConnection.Bitbucket]: TBitbucketConnection;
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@ export {
|
||||
useDeleteIntegrationAuth,
|
||||
useDeleteIntegrationAuths,
|
||||
useGetIntegrationAuthApps,
|
||||
useGetIntegrationAuthBitBucketWorkspaces,
|
||||
useGetIntegrationAuthBitbucketWorkspaces,
|
||||
useGetIntegrationAuthById,
|
||||
useGetIntegrationAuthChecklyGroups,
|
||||
useGetIntegrationAuthCircleCIOrganizations,
|
||||
|
||||
@@ -6,8 +6,8 @@ import { TReactQueryOptions } from "@app/types/reactQuery";
|
||||
import { workspaceKeys } from "../workspace";
|
||||
import {
|
||||
App,
|
||||
BitBucketEnvironment,
|
||||
BitBucketWorkspace,
|
||||
BitbucketEnvironment,
|
||||
BitbucketWorkspace,
|
||||
ChecklyGroup,
|
||||
CircleCIOrganization,
|
||||
Environment,
|
||||
@@ -98,9 +98,9 @@ const integrationAuthKeys = {
|
||||
integrationAuthId: string;
|
||||
appId: string;
|
||||
}) => [{ integrationAuthId, appId }, "integrationAuthRailwayServices"] as const,
|
||||
getIntegrationAuthBitBucketWorkspaces: (integrationAuthId: string) =>
|
||||
getIntegrationAuthBitbucketWorkspaces: (integrationAuthId: string) =>
|
||||
[{ integrationAuthId }, "integrationAuthBitbucketWorkspaces"] as const,
|
||||
getIntegrationAuthBitBucketEnvironments: (
|
||||
getIntegrationAuthBitbucketEnvironments: (
|
||||
integrationAuthId: string,
|
||||
workspaceSlug: string,
|
||||
repoSlug: string
|
||||
@@ -446,23 +446,23 @@ const fetchIntegrationAuthRailwayServices = async ({
|
||||
return services;
|
||||
};
|
||||
|
||||
const fetchIntegrationAuthBitBucketWorkspaces = async (integrationAuthId: string) => {
|
||||
const fetchIntegrationAuthBitbucketWorkspaces = async (integrationAuthId: string) => {
|
||||
const {
|
||||
data: { workspaces }
|
||||
} = await apiRequest.get<{ workspaces: BitBucketWorkspace[] }>(
|
||||
} = await apiRequest.get<{ workspaces: BitbucketWorkspace[] }>(
|
||||
`/api/v1/integration-auth/${integrationAuthId}/bitbucket/workspaces`
|
||||
);
|
||||
return workspaces;
|
||||
};
|
||||
|
||||
const fetchIntegrationAuthBitBucketEnvironments = async (
|
||||
const fetchIntegrationAuthBitbucketEnvironments = async (
|
||||
integrationAuthId: string,
|
||||
workspaceSlug: string,
|
||||
repoSlug: string
|
||||
) => {
|
||||
const {
|
||||
data: { environments }
|
||||
} = await apiRequest.get<{ environments: BitBucketEnvironment[] }>(
|
||||
} = await apiRequest.get<{ environments: BitbucketEnvironment[] }>(
|
||||
`/api/v1/integration-auth/${integrationAuthId}/bitbucket/environments`,
|
||||
{
|
||||
params: {
|
||||
@@ -833,10 +833,10 @@ export const useGetIntegrationAuthRailwayServices = ({
|
||||
});
|
||||
};
|
||||
|
||||
export const useGetIntegrationAuthBitBucketWorkspaces = (integrationAuthId: string) => {
|
||||
export const useGetIntegrationAuthBitbucketWorkspaces = (integrationAuthId: string) => {
|
||||
return useQuery({
|
||||
queryKey: integrationAuthKeys.getIntegrationAuthBitBucketWorkspaces(integrationAuthId),
|
||||
queryFn: () => fetchIntegrationAuthBitBucketWorkspaces(integrationAuthId),
|
||||
queryKey: integrationAuthKeys.getIntegrationAuthBitbucketWorkspaces(integrationAuthId),
|
||||
queryFn: () => fetchIntegrationAuthBitbucketWorkspaces(integrationAuthId),
|
||||
enabled: true
|
||||
});
|
||||
};
|
||||
@@ -858,7 +858,7 @@ export const useGetIntegrationAuthOctopusDeployScopeValues = (
|
||||
...options
|
||||
});
|
||||
|
||||
export const useGetIntegrationAuthBitBucketEnvironments = (
|
||||
export const useGetIntegrationAuthBitbucketEnvironments = (
|
||||
{
|
||||
integrationAuthId,
|
||||
workspaceSlug,
|
||||
@@ -871,13 +871,13 @@ export const useGetIntegrationAuthBitBucketEnvironments = (
|
||||
options?: TReactQueryOptions["options"]
|
||||
) => {
|
||||
return useQuery({
|
||||
queryKey: integrationAuthKeys.getIntegrationAuthBitBucketEnvironments(
|
||||
queryKey: integrationAuthKeys.getIntegrationAuthBitbucketEnvironments(
|
||||
integrationAuthId,
|
||||
workspaceSlug,
|
||||
repoSlug
|
||||
),
|
||||
queryFn: () =>
|
||||
fetchIntegrationAuthBitBucketEnvironments(integrationAuthId, workspaceSlug, repoSlug),
|
||||
fetchIntegrationAuthBitbucketEnvironments(integrationAuthId, workspaceSlug, repoSlug),
|
||||
...options
|
||||
});
|
||||
};
|
||||
|
||||
@@ -78,13 +78,13 @@ export type Service = {
|
||||
serviceId: string;
|
||||
};
|
||||
|
||||
export type BitBucketWorkspace = {
|
||||
export type BitbucketWorkspace = {
|
||||
uuid: string;
|
||||
name: string;
|
||||
slug: string;
|
||||
};
|
||||
|
||||
export type BitBucketEnvironment = {
|
||||
export type BitbucketEnvironment = {
|
||||
uuid: string;
|
||||
name: string;
|
||||
slug: string;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export enum SecretScanningDataSource {
|
||||
GitHub = "github",
|
||||
BitBucket = "bitbucket"
|
||||
Bitbucket = "bitbucket"
|
||||
}
|
||||
|
||||
export enum SecretScanningScanStatus {
|
||||
|
||||
@@ -3,15 +3,15 @@ import { AppConnection } from "@app/hooks/api/appConnections/enums";
|
||||
import { SecretScanningDataSource } from "../enums";
|
||||
import { TSecretScanningDataSourceBase } from "./shared";
|
||||
|
||||
export type TBitBucketDataSource = TSecretScanningDataSourceBase & {
|
||||
type: SecretScanningDataSource.BitBucket;
|
||||
export type TBitbucketDataSource = TSecretScanningDataSourceBase & {
|
||||
type: SecretScanningDataSource.Bitbucket;
|
||||
config: {
|
||||
includeRepos: string[];
|
||||
};
|
||||
};
|
||||
|
||||
export type TBitBucketDataSourceOption = {
|
||||
export type TBitbucketDataSourceOption = {
|
||||
name: string;
|
||||
type: SecretScanningDataSource.BitBucket;
|
||||
connection: AppConnection.BitBucket;
|
||||
type: SecretScanningDataSource.Bitbucket;
|
||||
connection: AppConnection.Bitbucket;
|
||||
};
|
||||
|
||||
@@ -8,10 +8,10 @@ import {
|
||||
SecretScanningScanStatus,
|
||||
SecretScanningScanType
|
||||
} from "../enums";
|
||||
import { TBitBucketDataSource, TBitBucketDataSourceOption } from "./bitbucket-data-source";
|
||||
import { TBitbucketDataSource, TBitbucketDataSourceOption } from "./bitbucket-data-source";
|
||||
import { TGitHubDataSource, TGitHubDataSourceOption } from "./github-data-source";
|
||||
|
||||
export type TSecretScanningDataSource = TGitHubDataSource | TBitBucketDataSource;
|
||||
export type TSecretScanningDataSource = TGitHubDataSource | TBitbucketDataSource;
|
||||
|
||||
export type TSecretScanningDataSourceWithDetails = TSecretScanningDataSource & {
|
||||
lastScannedAt: string | null;
|
||||
@@ -24,7 +24,7 @@ export type TListSecretScanningDataSources = {
|
||||
dataSources: TSecretScanningDataSourceWithDetails[];
|
||||
};
|
||||
|
||||
export type TSecretScanningDataSourceOption = TGitHubDataSourceOption | TBitBucketDataSourceOption;
|
||||
export type TSecretScanningDataSourceOption = TGitHubDataSourceOption | TBitbucketDataSourceOption;
|
||||
|
||||
export type TListSecretScanningDataSourceOptions = {
|
||||
dataSourceOptions: TSecretScanningDataSourceOption[];
|
||||
|
||||
+5
-5
@@ -16,7 +16,7 @@ import { AzureAppConfigurationConnectionForm } from "./AzureAppConfigurationConn
|
||||
import { AzureClientSecretsConnectionForm } from "./AzureClientSecretsConnectionForm";
|
||||
import { AzureDevOpsConnectionForm } from "./AzureDevOpsConnectionForm";
|
||||
import { AzureKeyVaultConnectionForm } from "./AzureKeyVaultConnectionForm";
|
||||
import { BitBucketConnectionForm } from "./BitBucketConnectionForm";
|
||||
import { BitbucketConnectionForm } from "./BitbucketConnectionForm";
|
||||
import { CamundaConnectionForm } from "./CamundaConnectionForm";
|
||||
import { CloudflareConnectionForm } from "./CloudflareConnectionForm";
|
||||
import { DatabricksConnectionForm } from "./DatabricksConnectionForm";
|
||||
@@ -135,8 +135,8 @@ const CreateForm = ({ app, onComplete }: CreateFormProps) => {
|
||||
return <GitLabConnectionForm onSubmit={onSubmit} />;
|
||||
case AppConnection.Cloudflare:
|
||||
return <CloudflareConnectionForm onSubmit={onSubmit} />;
|
||||
case AppConnection.BitBucket:
|
||||
return <BitBucketConnectionForm onSubmit={onSubmit} />;
|
||||
case AppConnection.Bitbucket:
|
||||
return <BitbucketConnectionForm onSubmit={onSubmit} />;
|
||||
default:
|
||||
throw new Error(`Unhandled App ${app}`);
|
||||
}
|
||||
@@ -231,8 +231,8 @@ const UpdateForm = ({ appConnection, onComplete }: UpdateFormProps) => {
|
||||
return <GitLabConnectionForm onSubmit={onSubmit} appConnection={appConnection} />;
|
||||
case AppConnection.Cloudflare:
|
||||
return <CloudflareConnectionForm onSubmit={onSubmit} appConnection={appConnection} />;
|
||||
case AppConnection.BitBucket:
|
||||
return <BitBucketConnectionForm onSubmit={onSubmit} appConnection={appConnection} />;
|
||||
case AppConnection.Bitbucket:
|
||||
return <BitbucketConnectionForm onSubmit={onSubmit} appConnection={appConnection} />;
|
||||
default:
|
||||
throw new Error(`Unhandled App ${(appConnection as TAppConnection).app}`);
|
||||
}
|
||||
|
||||
+10
-10
@@ -12,7 +12,7 @@ import {
|
||||
SelectItem
|
||||
} from "@app/components/v2";
|
||||
import { APP_CONNECTION_MAP, getAppConnectionMethodDetails } from "@app/helpers/appConnections";
|
||||
import { BitBucketConnectionMethod, TBitBucketConnection } from "@app/hooks/api/appConnections";
|
||||
import { BitbucketConnectionMethod, TBitbucketConnection } from "@app/hooks/api/appConnections";
|
||||
import { AppConnection } from "@app/hooks/api/appConnections/enums";
|
||||
|
||||
import {
|
||||
@@ -21,17 +21,17 @@ import {
|
||||
} from "./GenericAppConnectionFields";
|
||||
|
||||
type Props = {
|
||||
appConnection?: TBitBucketConnection;
|
||||
appConnection?: TBitbucketConnection;
|
||||
onSubmit: (formData: FormData) => void;
|
||||
};
|
||||
|
||||
const rootSchema = genericAppConnectionFieldsSchema.extend({
|
||||
app: z.literal(AppConnection.BitBucket)
|
||||
app: z.literal(AppConnection.Bitbucket)
|
||||
});
|
||||
|
||||
const formSchema = z.discriminatedUnion("method", [
|
||||
rootSchema.extend({
|
||||
method: z.literal(BitBucketConnectionMethod.ApiToken),
|
||||
method: z.literal(BitbucketConnectionMethod.ApiToken),
|
||||
credentials: z.object({
|
||||
email: z.string().email().trim().min(1, "Email required"),
|
||||
apiToken: z.string().trim().min(1, "API Token required")
|
||||
@@ -41,14 +41,14 @@ const formSchema = z.discriminatedUnion("method", [
|
||||
|
||||
type FormData = z.infer<typeof formSchema>;
|
||||
|
||||
export const BitBucketConnectionForm = ({ appConnection, onSubmit }: Props) => {
|
||||
export const BitbucketConnectionForm = ({ appConnection, onSubmit }: Props) => {
|
||||
const isUpdate = Boolean(appConnection);
|
||||
|
||||
const form = useForm<FormData>({
|
||||
resolver: zodResolver(formSchema),
|
||||
defaultValues: appConnection ?? {
|
||||
app: AppConnection.BitBucket,
|
||||
method: BitBucketConnectionMethod.ApiToken
|
||||
app: AppConnection.Bitbucket,
|
||||
method: BitbucketConnectionMethod.ApiToken
|
||||
}
|
||||
});
|
||||
|
||||
@@ -68,7 +68,7 @@ export const BitBucketConnectionForm = ({ appConnection, onSubmit }: Props) => {
|
||||
render={({ field: { value, onChange }, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
tooltipText={`The method you would like to use to connect with ${
|
||||
APP_CONNECTION_MAP[AppConnection.BitBucket].name
|
||||
APP_CONNECTION_MAP[AppConnection.Bitbucket].name
|
||||
}. This field cannot be changed after creation.`}
|
||||
errorText={error?.message}
|
||||
isError={Boolean(error?.message)}
|
||||
@@ -82,7 +82,7 @@ export const BitBucketConnectionForm = ({ appConnection, onSubmit }: Props) => {
|
||||
position="popper"
|
||||
dropdownContainerClassName="max-w-none"
|
||||
>
|
||||
{Object.values(BitBucketConnectionMethod).map((method) => {
|
||||
{Object.values(BitbucketConnectionMethod).map((method) => {
|
||||
return (
|
||||
<SelectItem value={method} key={method}>
|
||||
{getAppConnectionMethodDetails(method).name}{" "}
|
||||
@@ -130,7 +130,7 @@ export const BitBucketConnectionForm = ({ appConnection, onSubmit }: Props) => {
|
||||
isLoading={isSubmitting}
|
||||
isDisabled={isSubmitting || !isDirty}
|
||||
>
|
||||
{isUpdate ? "Update Credentials" : "Connect to BitBucket"}
|
||||
{isUpdate ? "Update Credentials" : "Connect to Bitbucket"}
|
||||
</Button>
|
||||
<ModalClose asChild>
|
||||
<Button colorSchema="secondary" variant="plain">
|
||||
|
||||
+4
-4
@@ -20,9 +20,9 @@ import { useWorkspace } from "@app/context";
|
||||
import {
|
||||
useCreateIntegration,
|
||||
useGetIntegrationAuthApps,
|
||||
useGetIntegrationAuthBitBucketWorkspaces
|
||||
useGetIntegrationAuthBitbucketWorkspaces
|
||||
} from "@app/hooks/api";
|
||||
import { useGetIntegrationAuthBitBucketEnvironments } from "@app/hooks/api/integrationAuth/queries";
|
||||
import { useGetIntegrationAuthBitbucketEnvironments } from "@app/hooks/api/integrationAuth/queries";
|
||||
import { IntegrationsListPageTabs } from "@app/types/integrations";
|
||||
|
||||
enum BitbucketScope {
|
||||
@@ -99,7 +99,7 @@ export const BitbucketConfigurePage = () => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
|
||||
const { data: bitbucketWorkspaces, isPending: isBitbucketWorkspacesLoading } =
|
||||
useGetIntegrationAuthBitBucketWorkspaces((integrationAuthId as string) ?? "");
|
||||
useGetIntegrationAuthBitbucketWorkspaces((integrationAuthId as string) ?? "");
|
||||
|
||||
const { data: bitbucketRepos, isPending: isBitbucketReposLoading } = useGetIntegrationAuthApps({
|
||||
integrationAuthId: (integrationAuthId as string) ?? "",
|
||||
@@ -107,7 +107,7 @@ export const BitbucketConfigurePage = () => {
|
||||
});
|
||||
|
||||
const { data: bitbucketEnvironments, isPending: isBitbucketEnvironmentsLoading } =
|
||||
useGetIntegrationAuthBitBucketEnvironments(
|
||||
useGetIntegrationAuthBitbucketEnvironments(
|
||||
{
|
||||
integrationAuthId: (integrationAuthId as string) ?? "",
|
||||
workspaceSlug: bitBucketWorkspace?.slug ?? "",
|
||||
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
import { GenericFieldLabel } from "@app/components/v2";
|
||||
import { TBitBucketDataSource } from "@app/hooks/api/secretScanningV2/types/bitbucket-data-source";
|
||||
import { TBitbucketDataSource } from "@app/hooks/api/secretScanningV2/types/bitbucket-data-source";
|
||||
|
||||
type Props = {
|
||||
dataSource: TBitBucketDataSource;
|
||||
dataSource: TBitbucketDataSource;
|
||||
};
|
||||
|
||||
export const BitBucketDataSourceConfigDisplay = ({ dataSource }: Props) => {
|
||||
export const BitbucketDataSourceConfigDisplay = ({ dataSource }: Props) => {
|
||||
const {
|
||||
config: { includeRepos }
|
||||
} = dataSource;
|
||||
|
||||
+3
-3
@@ -3,8 +3,8 @@ import {
|
||||
TSecretScanningDataSource
|
||||
} from "@app/hooks/api/secretScanningV2";
|
||||
|
||||
import { BitbucketDataSourceConfigDisplay } from "./BitbucketDataSourceConfigDisplay";
|
||||
import { GitHubDataSourceConfigDisplay } from "./GitHubDataSourceConfigDisplay";
|
||||
import { BitBucketDataSourceConfigDisplay } from "./BitBucketDataSourceConfigDisplay";
|
||||
|
||||
type Props = {
|
||||
dataSource: TSecretScanningDataSource;
|
||||
@@ -14,8 +14,8 @@ export const DataSourceConfigDisplay = ({ dataSource }: Props) => {
|
||||
switch (dataSource.type) {
|
||||
case SecretScanningDataSource.GitHub:
|
||||
return <GitHubDataSourceConfigDisplay dataSource={dataSource} />;
|
||||
case SecretScanningDataSource.BitBucket:
|
||||
return <BitBucketDataSourceConfigDisplay dataSource={dataSource} />;
|
||||
case SecretScanningDataSource.Bitbucket:
|
||||
return <BitbucketDataSourceConfigDisplay dataSource={dataSource} />;
|
||||
default:
|
||||
throw new Error(
|
||||
`Unhandled dataSource type ${(dataSource as TSecretScanningDataSource).type}`
|
||||
|
||||
Reference in New Issue
Block a user