diff --git a/backend/src/services/integration-auth/integration-app-list.ts b/backend/src/services/integration-auth/integration-app-list.ts index 2c518db1b..d6930c594 100644 --- a/backend/src/services/integration-auth/integration-app-list.ts +++ b/backend/src/services/integration-auth/integration-app-list.ts @@ -459,10 +459,9 @@ const getAppsFlyio = async ({ accessToken }: { accessToken: string }) => { * Return list of projects for CircleCI integration */ const getAppsCircleCI = async ({ accessToken }: { accessToken: string }) => { - // Fetch collaborations (v2 API) - const collaborations = ( - await request.get<{ id: string; name: string; slug: string }[]>( - `${IntegrationUrls.CIRCLECI_API_URL}/v2/me/collaborations`, + const res = ( + await request.get<{ reponame: string; username: string; vcs_url: string }[]>( + `${IntegrationUrls.CIRCLECI_API_URL}/v1.1/projects`, { headers: { "Circle-Token": accessToken, @@ -472,9 +471,10 @@ const getAppsCircleCI = async ({ accessToken }: { accessToken: string }) => { ) ).data; - const apps = collaborations.map((a) => ({ - name: a.name, - appId: a.id + const apps = res.map((a) => ({ + owner: a.username, // username maps to unique organization name in CircleCI + name: a.reponame, // reponame maps to project name within an organization in CircleCI + appId: a.vcs_url.split("/").pop() // vcs_url maps to the project id in CircleCI })); return apps; diff --git a/backend/src/services/integration-auth/integration-auth-types.ts b/backend/src/services/integration-auth/integration-auth-types.ts index 7d59fda27..af390297a 100644 --- a/backend/src/services/integration-auth/integration-auth-types.ts +++ b/backend/src/services/integration-auth/integration-auth-types.ts @@ -143,12 +143,6 @@ export type TBitbucketWorkspace = { updated_on: string; }; -export enum CircleCiVcsType { - GitHub = "GitHub", - CircleCI = "CircleCI", - BitBucket = "BitBucket" -} - export type TNorthflankSecretGroup = { id: string; name: string; diff --git a/backend/src/services/integration-auth/integration-sync-secret.ts b/backend/src/services/integration-auth/integration-sync-secret.ts index 00168b6e3..eb8645530 100644 --- a/backend/src/services/integration-auth/integration-sync-secret.ts +++ b/backend/src/services/integration-auth/integration-sync-secret.ts @@ -35,7 +35,7 @@ import { TCreateManySecretsRawFn, TUpdateManySecretsRawFn } from "@app/services/ import { TIntegrationDALFactory } from "../integration/integration-dal"; import { IntegrationMetadataSchema } from "../integration/integration-schema"; -import { CircleCiVcsType, TIntegrationsWithEnvironment } from "./integration-auth-types"; +import { TIntegrationsWithEnvironment } from "./integration-auth-types"; import { IntegrationInitialSyncBehavior, IntegrationMappingBehavior, @@ -1929,8 +1929,9 @@ const syncSecretsCircleCI = async ({ secrets: Record; accessToken: string; }) => { - const circleciOrganizationDetail = ( - await request.get<{ slug: string; name: string }[]>(`${IntegrationUrls.CIRCLECI_API_URL}/v2/me/collaborations`, { + let projectSlug: string | null = null; + const projectDetails = ( + await request.get<{ slug: string }>(`${IntegrationUrls.CIRCLECI_API_URL}/v2/project/${integration.appId}`, { headers: { "Circle-Token": accessToken, "Accept-Encoding": "application/json" @@ -1938,30 +1939,7 @@ const syncSecretsCircleCI = async ({ }) ).data; - let projectSlug: string | null = null; - if (!integration.owner) { - projectSlug = `${circleciOrganizationDetail[0].slug}/${integration.app}`; - } else { - const projectDetails = ( - await request.get<{ vcs_info: { provider: CircleCiVcsType } }>( - `${IntegrationUrls.CIRCLECI_API_URL}/v2/project/${integration.app}`, - { - headers: { - "Circle-Token": accessToken, - "Accept-Encoding": "application/json" - } - } - ) - ).data; - - const vcsProviderMap: Record = { - [CircleCiVcsType.GitHub]: "gh", - [CircleCiVcsType.BitBucket]: "bb", - [CircleCiVcsType.CircleCI]: "circleci" - }; - - projectSlug = `${vcsProviderMap[projectDetails.vcs_info.provider]}/${integration.owner}/${integration.app}`; - } + projectSlug = `${projectDetails.slug}`; // sync secrets to CircleCI await Promise.all( diff --git a/frontend/src/pages/integrations/aws-parameter-store/authorize.tsx b/frontend/src/pages/integrations/aws-parameter-store/authorize.tsx index b3eb5fa88..1b208c394 100644 --- a/frontend/src/pages/integrations/aws-parameter-store/authorize.tsx +++ b/frontend/src/pages/integrations/aws-parameter-store/authorize.tsx @@ -69,7 +69,7 @@ export default function AWSParameterStoreAuthorizeIntegrationPage() { subTitle="After adding the details below, you will be prompted to set up an integration for a particular Infisical project and environment." >
-
+
integrationAuthApp.appId === targetProjectId + ); + + if (!selectedApp) { + createNotification({ + type: "error", + text: "Invalid project selected" + }); + return; + } + await mutateAsync({ integrationAuthId: integrationAuth?.id, isActive: true, - app: targetApp, - owner: targetOrganization, - appId: integrationAuthApps?.find( - (integrationAuthApp) => integrationAuthApp.name === targetApp - )?.appId, + app: selectedApp.name, // project name + owner: selectedApp.owner, // organization name + appId: selectedApp.appId, // project id (used for syncing) sourceEnvironment: selectedSourceEnvironment, secretPath }); @@ -86,6 +103,14 @@ export default function CircleCICreateIntegrationPage() { } }; + const filteredProjects = useMemo(() => { + if (!integrationAuthApps) return []; + + return integrationAuthApps.filter((integrationAuthApp) => { + return integrationAuthApp.owner === targetOrganization; + }); + }, [integrationAuthApps, targetOrganization]); + return integrationAuth && workspace && selectedSourceEnvironment && integrationAuthApps ? (
@@ -151,6 +176,7 @@ export default function CircleCICreateIntegrationPage() { value={targetOrganization} onValueChange={(val) => { setTargetOrganization(val); + setTargetProjectId("none"); }} className="w-full border border-mineshaft-500" isDisabled={integrationAuthApps.length === 0} @@ -158,10 +184,10 @@ export default function CircleCICreateIntegrationPage() { {integrationAuthApps.length > 0 ? ( integrationAuthApps.map((integrationAuthApp) => ( - {integrationAuthApp.name} + {integrationAuthApp.owner} )) ) : ( @@ -174,11 +200,26 @@ export default function CircleCICreateIntegrationPage() { {targetOrganization && ( - setTargetApp(evt.target.value)} - /> + )}
)} + {integration.integration === "circleci" && integration.owner && ( +
+ +
+ {integration.owner} +
+
+ )} {integration.integration === "terraform-cloud" && integration.targetService && (