mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
misc: addressed review comments
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
/* eslint-disable no-await-in-loop */
|
|
||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError } from "@casl/ability";
|
||||||
import { createAppAuth } from "@octokit/auth-app";
|
import { createAppAuth } from "@octokit/auth-app";
|
||||||
import { Octokit } from "@octokit/rest";
|
import { Octokit } from "@octokit/rest";
|
||||||
@@ -12,6 +11,7 @@ import { getConfig } from "@app/lib/config/env";
|
|||||||
import { request } from "@app/lib/config/request";
|
import { request } from "@app/lib/config/request";
|
||||||
import { decryptSymmetric128BitHexKeyUTF8, encryptSymmetric128BitHexKeyUTF8 } from "@app/lib/crypto";
|
import { decryptSymmetric128BitHexKeyUTF8, encryptSymmetric128BitHexKeyUTF8 } from "@app/lib/crypto";
|
||||||
import { BadRequestError, InternalServerError, NotFoundError } from "@app/lib/errors";
|
import { BadRequestError, InternalServerError, NotFoundError } from "@app/lib/errors";
|
||||||
|
import { groupBy } from "@app/lib/fn";
|
||||||
import { logger } from "@app/lib/logger";
|
import { logger } from "@app/lib/logger";
|
||||||
import { TGenericPermission, TProjectPermission } from "@app/lib/types";
|
import { TGenericPermission, TProjectPermission } from "@app/lib/types";
|
||||||
|
|
||||||
@@ -1634,58 +1634,40 @@ export const integrationAuthServiceFactory = ({
|
|||||||
logger.error(error);
|
logger.error(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
const projectsByOrg = projects.reduce<Record<string, { name: string; id: string }[]>>((accum, project) => {
|
const projectsByOrg = groupBy(
|
||||||
if (!accum[project.orgName]) {
|
projects.map((p) => ({
|
||||||
return {
|
orgName: p.orgName,
|
||||||
...accum,
|
name: p.projectName,
|
||||||
[project.orgName]: [
|
id: p.projectId
|
||||||
{
|
})),
|
||||||
name: project.projectName,
|
(p) => p.orgName
|
||||||
id: project.projectId as string
|
);
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
...accum,
|
|
||||||
[project.orgName]: [
|
|
||||||
...accum[project.orgName],
|
|
||||||
{
|
|
||||||
name: project.projectName,
|
|
||||||
id: project.projectId as string
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
const getOrgContexts = async (orgSlug: string) => {
|
const getOrgContexts = async (orgSlug: string) => {
|
||||||
type NextPageToken = string | null | undefined;
|
type NextPageToken = string | null | undefined;
|
||||||
|
|
||||||
type CircleCIContextResponse = {
|
|
||||||
items: TCircleCIContext[];
|
|
||||||
next_page_token: NextPageToken;
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const contexts: TCircleCIContext[] = [];
|
const contexts: TCircleCIContext[] = [];
|
||||||
let nextPageToken: NextPageToken;
|
let nextPageToken: NextPageToken;
|
||||||
|
|
||||||
while (nextPageToken !== null) {
|
while (nextPageToken !== null) {
|
||||||
const res = (
|
// eslint-disable-next-line no-await-in-loop
|
||||||
await request.get<CircleCIContextResponse>(`${IntegrationUrls.CIRCLECI_API_URL}/v2/context`, {
|
const { data } = await request.get<{
|
||||||
headers: {
|
items: TCircleCIContext[];
|
||||||
"Circle-Token": accessToken,
|
next_page_token: NextPageToken;
|
||||||
"Accept-Encoding": "application/json"
|
}>(`${IntegrationUrls.CIRCLECI_API_URL}/v2/context`, {
|
||||||
},
|
headers: {
|
||||||
params: new URLSearchParams({
|
"Circle-Token": accessToken,
|
||||||
"owner-slug": orgSlug,
|
"Accept-Encoding": "application/json"
|
||||||
...(nextPageToken ? { "page-token": nextPageToken } : {})
|
},
|
||||||
})
|
params: new URLSearchParams({
|
||||||
|
"owner-slug": orgSlug,
|
||||||
|
...(nextPageToken ? { "page-token": nextPageToken } : {})
|
||||||
})
|
})
|
||||||
).data;
|
});
|
||||||
|
|
||||||
contexts.push(...res.items);
|
contexts.push(...data.items);
|
||||||
nextPageToken = res.next_page_token;
|
nextPageToken = data.next_page_token;
|
||||||
}
|
}
|
||||||
|
|
||||||
return contexts?.map((context) => ({
|
return contexts?.map((context) => ({
|
||||||
|
|||||||
@@ -227,6 +227,11 @@ export enum OctopusDeployScope {
|
|||||||
// add tenant, variable set, etc.
|
// add tenant, variable set, etc.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum CircleCiScope {
|
||||||
|
Project = "project",
|
||||||
|
Context = "context"
|
||||||
|
}
|
||||||
|
|
||||||
export type TOctopusDeployVariableSet = {
|
export type TOctopusDeployVariableSet = {
|
||||||
Id: string;
|
Id: string;
|
||||||
OwnerId: string;
|
OwnerId: string;
|
||||||
|
|||||||
@@ -76,8 +76,6 @@ export enum IntegrationUrls {
|
|||||||
RAILWAY_API_URL = "https://backboard.railway.app/graphql/v2",
|
RAILWAY_API_URL = "https://backboard.railway.app/graphql/v2",
|
||||||
FLYIO_API_URL = "https://api.fly.io/graphql",
|
FLYIO_API_URL = "https://api.fly.io/graphql",
|
||||||
CIRCLECI_API_URL = "https://circleci.com/api",
|
CIRCLECI_API_URL = "https://circleci.com/api",
|
||||||
// eslint-disable-next-line
|
|
||||||
DATABRICKS_API_URL = "https:/xxxx.com/api",
|
|
||||||
TRAVISCI_API_URL = "https://api.travis-ci.com",
|
TRAVISCI_API_URL = "https://api.travis-ci.com",
|
||||||
SUPABASE_API_URL = "https://api.supabase.com",
|
SUPABASE_API_URL = "https://api.supabase.com",
|
||||||
LARAVELFORGE_API_URL = "https://forge.laravel.com",
|
LARAVELFORGE_API_URL = "https://forge.laravel.com",
|
||||||
|
|||||||
@@ -39,7 +39,12 @@ import { TCreateManySecretsRawFn, TUpdateManySecretsRawFn } from "@app/services/
|
|||||||
import { TIntegrationDALFactory } from "../integration/integration-dal";
|
import { TIntegrationDALFactory } from "../integration/integration-dal";
|
||||||
import { IntegrationMetadataSchema } from "../integration/integration-schema";
|
import { IntegrationMetadataSchema } from "../integration/integration-schema";
|
||||||
import { IntegrationAuthMetadataSchema } from "./integration-auth-schema";
|
import { IntegrationAuthMetadataSchema } from "./integration-auth-schema";
|
||||||
import { OctopusDeployScope, TIntegrationsWithEnvironment, TOctopusDeployVariableSet } from "./integration-auth-types";
|
import {
|
||||||
|
CircleCiScope,
|
||||||
|
OctopusDeployScope,
|
||||||
|
TIntegrationsWithEnvironment,
|
||||||
|
TOctopusDeployVariableSet
|
||||||
|
} from "./integration-auth-types";
|
||||||
import {
|
import {
|
||||||
IntegrationInitialSyncBehavior,
|
IntegrationInitialSyncBehavior,
|
||||||
IntegrationMappingBehavior,
|
IntegrationMappingBehavior,
|
||||||
@@ -2245,11 +2250,6 @@ const syncSecretsCircleCI = async ({
|
|||||||
secrets: Record<string, { value: string; comment?: string }>;
|
secrets: Record<string, { value: string; comment?: string }>;
|
||||||
accessToken: string;
|
accessToken: string;
|
||||||
}) => {
|
}) => {
|
||||||
enum CircleCiScope {
|
|
||||||
Project = "project",
|
|
||||||
Context = "context"
|
|
||||||
}
|
|
||||||
|
|
||||||
if (integration.scope === CircleCiScope.Context) {
|
if (integration.scope === CircleCiScope.Context) {
|
||||||
// sync secrets to CircleCI
|
// sync secrets to CircleCI
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
@@ -2278,29 +2278,24 @@ const syncSecretsCircleCI = async ({
|
|||||||
context_id: string;
|
context_id: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ResponseSchema = {
|
|
||||||
items: EnvVars[];
|
|
||||||
next_page_token: string | null;
|
|
||||||
};
|
|
||||||
|
|
||||||
let nextPageToken: string | null | undefined;
|
let nextPageToken: string | null | undefined;
|
||||||
const envVars: EnvVars[] = [];
|
const envVars: EnvVars[] = [];
|
||||||
|
|
||||||
while (nextPageToken !== null) {
|
while (nextPageToken !== null) {
|
||||||
const res = await request.get<ResponseSchema>(
|
const res = await request.get<{
|
||||||
`${IntegrationUrls.CIRCLECI_API_URL}/v2/context/${integration.appId}/environment-variable`,
|
items: EnvVars[];
|
||||||
{
|
next_page_token: string | null;
|
||||||
headers: {
|
}>(`${IntegrationUrls.CIRCLECI_API_URL}/v2/context/${integration.appId}/environment-variable`, {
|
||||||
"Circle-Token": accessToken,
|
headers: {
|
||||||
"Accept-Encoding": "application/json"
|
"Circle-Token": accessToken,
|
||||||
},
|
"Accept-Encoding": "application/json"
|
||||||
params: nextPageToken
|
},
|
||||||
? new URLSearchParams({
|
params: nextPageToken
|
||||||
"page-token": nextPageToken
|
? new URLSearchParams({
|
||||||
})
|
"page-token": nextPageToken
|
||||||
: undefined
|
})
|
||||||
}
|
: undefined
|
||||||
);
|
});
|
||||||
|
|
||||||
envVars.push(...res.data.items);
|
envVars.push(...res.data.items);
|
||||||
nextPageToken = res.data.next_page_token;
|
nextPageToken = res.data.next_page_token;
|
||||||
|
|||||||
@@ -138,3 +138,8 @@ export type TOctopusDeployVariableSetScopeValues = {
|
|||||||
Name: string;
|
Name: string;
|
||||||
}[];
|
}[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export enum CircleCiScope {
|
||||||
|
Context = "context",
|
||||||
|
Project = "project"
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,17 +22,18 @@ import { SecretPathInput } from "@app/components/v2/SecretPathInput";
|
|||||||
import { useWorkspace } from "@app/context";
|
import { useWorkspace } from "@app/context";
|
||||||
import { useCreateIntegration } from "@app/hooks/api";
|
import { useCreateIntegration } from "@app/hooks/api";
|
||||||
import { useGetIntegrationAuthCircleCIOrganizations } from "@app/hooks/api/integrationAuth";
|
import { useGetIntegrationAuthCircleCIOrganizations } from "@app/hooks/api/integrationAuth";
|
||||||
|
import { CircleCiScope } from "@app/hooks/api/integrationAuth/types";
|
||||||
|
|
||||||
const formSchema = z.discriminatedUnion("scope", [
|
const formSchema = z.discriminatedUnion("scope", [
|
||||||
z.object({
|
z.object({
|
||||||
scope: z.literal("context"),
|
scope: z.literal(CircleCiScope.Context),
|
||||||
secretPath: z.string().default("/"),
|
secretPath: z.string().default("/"),
|
||||||
sourceEnvironment: z.object({ name: z.string(), slug: z.string() }),
|
sourceEnvironment: z.object({ name: z.string(), slug: z.string() }),
|
||||||
targetOrg: z.object({ name: z.string().min(1), slug: z.string().min(1) }),
|
targetOrg: z.object({ name: z.string().min(1), slug: z.string().min(1) }),
|
||||||
targetContext: z.object({ name: z.string().min(1), id: z.string().min(1) })
|
targetContext: z.object({ name: z.string().min(1), id: z.string().min(1) })
|
||||||
}),
|
}),
|
||||||
z.object({
|
z.object({
|
||||||
scope: z.literal("project"),
|
scope: z.literal(CircleCiScope.Project),
|
||||||
secretPath: z.string().default("/"),
|
secretPath: z.string().default("/"),
|
||||||
sourceEnvironment: z.object({ name: z.string(), slug: z.string() }),
|
sourceEnvironment: z.object({ name: z.string(), slug: z.string() }),
|
||||||
targetOrg: z.object({ name: z.string().min(1), slug: z.string().min(1) }),
|
targetOrg: z.object({ name: z.string().min(1), slug: z.string().min(1) }),
|
||||||
@@ -69,7 +70,7 @@ export default function CircleCICreateIntegrationPage() {
|
|||||||
|
|
||||||
const onSubmit = async (data: TFormData) => {
|
const onSubmit = async (data: TFormData) => {
|
||||||
try {
|
try {
|
||||||
if (data.scope === "context") {
|
if (data.scope === CircleCiScope.Context) {
|
||||||
await mutateAsync({
|
await mutateAsync({
|
||||||
scope: data.scope,
|
scope: data.scope,
|
||||||
integrationAuthId,
|
integrationAuthId,
|
||||||
@@ -231,13 +232,13 @@ export default function CircleCICreateIntegrationPage() {
|
|||||||
}}
|
}}
|
||||||
className="w-full border border-mineshaft-500"
|
className="w-full border border-mineshaft-500"
|
||||||
>
|
>
|
||||||
<SelectItem value="project">Project</SelectItem>
|
<SelectItem value={CircleCiScope.Project}>Project</SelectItem>
|
||||||
<SelectItem value="context">Context</SelectItem>
|
<SelectItem value={CircleCiScope.Context}>Context</SelectItem>
|
||||||
</Select>
|
</Select>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
{selectedScope === "context" && selectedOrganizationEntry && (
|
{selectedScope === CircleCiScope.Context && selectedOrganizationEntry && (
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="targetContext"
|
name="targetContext"
|
||||||
@@ -264,7 +265,7 @@ export default function CircleCICreateIntegrationPage() {
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{selectedScope === "project" && selectedOrganizationEntry && (
|
{selectedScope === CircleCiScope.Project && selectedOrganizationEntry && (
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="targetProject"
|
name="targetProject"
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { integrationSlugNameMapping } from "public/data/frequentConstants";
|
import { integrationSlugNameMapping } from "public/data/frequentConstants";
|
||||||
|
|
||||||
import { FormLabel } from "@app/components/v2";
|
import { FormLabel } from "@app/components/v2";
|
||||||
|
import { CircleCiScope } from "@app/hooks/api/integrationAuth/types";
|
||||||
import { IntegrationMappingBehavior, TIntegrationWithEnv } from "@app/hooks/api/integrations/types";
|
import { IntegrationMappingBehavior, TIntegrationWithEnv } from "@app/hooks/api/integrations/types";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@@ -46,7 +47,7 @@ export const IntegrationConnectionSection = ({ integration }: Props) => {
|
|||||||
case "qovery":
|
case "qovery":
|
||||||
return integration.scope;
|
return integration.scope;
|
||||||
case "circleci":
|
case "circleci":
|
||||||
if (integration.scope === "context") {
|
if (integration.scope === CircleCiScope.Context) {
|
||||||
return "Context";
|
return "Context";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { FormLabel } from "@app/components/v2";
|
import { FormLabel } from "@app/components/v2";
|
||||||
|
import { CircleCiScope } from "@app/hooks/api/integrationAuth/types";
|
||||||
import { IntegrationMappingBehavior, TIntegration } from "@app/hooks/api/integrations/types";
|
import { IntegrationMappingBehavior, TIntegration } from "@app/hooks/api/integrations/types";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@@ -53,7 +54,7 @@ export const IntegrationDetails = ({ integration }: Props) => {
|
|||||||
label={
|
label={
|
||||||
(integration.integration === "qovery" && integration?.scope) ||
|
(integration.integration === "qovery" && integration?.scope) ||
|
||||||
(integration.integration === "circleci" &&
|
(integration.integration === "circleci" &&
|
||||||
(integration.scope === "context" ? "Context" : "Project")) ||
|
(integration.scope === CircleCiScope.Context ? "Context" : "Project")) ||
|
||||||
(integration.integration === "bitbucket" && "Repository") ||
|
(integration.integration === "bitbucket" && "Repository") ||
|
||||||
(integration.integration === "octopus-deploy" && "Project") ||
|
(integration.integration === "octopus-deploy" && "Project") ||
|
||||||
(integration.integration === "aws-secret-manager" && "Secret") ||
|
(integration.integration === "aws-secret-manager" && "Secret") ||
|
||||||
|
|||||||
Reference in New Issue
Block a user