feat(infisical-pg): changed frontend api types _id to normal id

This commit is contained in:
Akhil Mohan
2024-01-27 12:38:22 +05:30
parent f3b37de3f3
commit aaba4a0895
161 changed files with 5358 additions and 4510 deletions
@@ -6,16 +6,14 @@ import { useRouter } from "next/router";
import { faArrowUpRightFromSquare, faBookOpen } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
useSaveIntegrationAccessToken
} from "@app/hooks/api";
import { useSaveIntegrationAccessToken } from "@app/hooks/api";
import { Button, Card, CardTitle, FormControl, Input } from "../../../components/v2";
export default function AWSParameterStoreAuthorizeIntegrationPage() {
const router = useRouter();
const { mutateAsync } = useSaveIntegrationAccessToken();
const [isLoading, setIsLoading] = useState(false);
const [accessKey, setAccessKey] = useState("");
@@ -63,11 +61,11 @@ export default function AWSParameterStoreAuthorizeIntegrationPage() {
<div className="flex h-full w-full items-center justify-center">
<Head>
<title>Authorize AWS Parameter Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
<Card className="max-w-lg rounded-md border border-mineshaft-600">
<CardTitle
className="text-left px-6 text-xl"
<CardTitle
className="px-6 text-left text-xl"
subTitle="After adding the details below, you will be prompted to set up an integration for a particular Infisical project and environment."
>
<div className="flex flex-row items-center">
@@ -82,10 +80,13 @@ export default function AWSParameterStoreAuthorizeIntegrationPage() {
<span className="ml-1.5">AWS Parameter Store Integration </span>
<Link href="https://infisical.com/docs/integrations/cloud/aws-parameter-store" passHref>
<a target="_blank" rel="noopener noreferrer">
<div className="ml-2 mb-1 rounded-md text-yellow text-sm inline-block bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] opacity-80 hover:opacity-100 cursor-default">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5"/>
<div className="ml-2 mb-1 inline-block cursor-default rounded-md bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] text-sm text-yellow opacity-80 hover:opacity-100">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
Docs
<FontAwesomeIcon icon={faArrowUpRightFromSquare} className="ml-1.5 text-xxs mb-[0.07rem]"/>
<FontAwesomeIcon
icon={faArrowUpRightFromSquare}
className="ml-1.5 mb-[0.07rem] text-xxs"
/>
</div>
</a>
</Link>
@@ -97,11 +98,7 @@ export default function AWSParameterStoreAuthorizeIntegrationPage() {
isError={accessKeyErrorText !== "" ?? false}
className="px-6"
>
<Input
placeholder=""
value={accessKey}
onChange={(e) => setAccessKey(e.target.value)}
/>
<Input placeholder="" value={accessKey} onChange={(e) => setAccessKey(e.target.value)} />
</FormControl>
<FormControl
label="Secret Access Key"
@@ -3,13 +3,16 @@ import Head from "next/head";
import Image from "next/image";
import Link from "next/link";
import { useRouter } from "next/router";
import { faArrowUpRightFromSquare, faBookOpen, faBugs, faCircleInfo } from "@fortawesome/free-solid-svg-icons";
import {
faArrowUpRightFromSquare,
faBookOpen,
faBugs,
faCircleInfo
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import queryString from "query-string";
import {
useCreateIntegration
} from "@app/hooks/api";
import { useCreateIntegration } from "@app/hooks/api";
import {
Button,
@@ -62,7 +65,9 @@ export default function AWSParameterStoreCreateIntegrationPage() {
const { integrationAuthId } = queryString.parse(router.asPath.split("?")[1]);
const { data: workspace } = useGetWorkspaceById(localStorage.getItem("projectData.id") ?? "");
const { data: integrationAuth, isLoading: isintegrationAuthLoading } = useGetIntegrationAuthById((integrationAuthId as string) ?? "");
const { data: integrationAuth, isLoading: isintegrationAuthLoading } = useGetIntegrationAuthById(
(integrationAuthId as string) ?? ""
);
const [selectedSourceEnvironment, setSelectedSourceEnvironment] = useState("");
const [secretPath, setSecretPath] = useState("/");
@@ -118,14 +123,14 @@ export default function AWSParameterStoreCreateIntegrationPage() {
};
return integrationAuth && workspace && selectedSourceEnvironment ? (
<div className="flex flex-col h-full w-full items-center justify-center">
<div className="flex h-full w-full flex-col items-center justify-center">
<Head>
<title>Set Up AWS Parameter Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
<Card className="max-w-lg rounded-md border border-mineshaft-600">
<CardTitle
className="text-left px-6 text-xl"
<CardTitle
className="px-6 text-left text-xl"
subTitle="Choose which environment in Infisical you want to sync to secerts in AWS Parameter Store."
>
<div className="flex flex-row items-center">
@@ -140,10 +145,13 @@ export default function AWSParameterStoreCreateIntegrationPage() {
<span className="ml-1.5">AWS Parameter Store Integration </span>
<Link href="https://infisical.com/docs/integrations/cloud/aws-parameter-store" passHref>
<a target="_blank" rel="noopener noreferrer">
<div className="ml-2 mb-1 rounded-md text-yellow text-sm inline-block bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] opacity-80 hover:opacity-100 cursor-default">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5"/>
<div className="ml-2 mb-1 inline-block cursor-default rounded-md bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] text-sm text-yellow opacity-80 hover:opacity-100">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
Docs
<FontAwesomeIcon icon={faArrowUpRightFromSquare} className="ml-1.5 text-xxs mb-[0.07rem]"/>
<FontAwesomeIcon
icon={faArrowUpRightFromSquare}
className="ml-1.5 mb-[0.07rem] text-xxs"
/>
</div>
</a>
</Link>
@@ -185,7 +193,12 @@ export default function AWSParameterStoreCreateIntegrationPage() {
))}
</Select>
</FormControl>
<FormControl label="Path" errorText={pathErrorText} isError={pathErrorText !== "" ?? false} className="px-6">
<FormControl
label="Path"
errorText={pathErrorText}
isError={pathErrorText !== "" ?? false}
className="px-6"
>
<Input
placeholder={`/${workspace.name
.toLowerCase()
@@ -204,31 +217,49 @@ export default function AWSParameterStoreCreateIntegrationPage() {
Create Integration
</Button>
</Card>
<div className="border-t border-mineshaft-800 w-full max-w-md mt-6"/>
<div className="flex flex-col bg-mineshaft-800 border border-mineshaft-600 w-full p-4 max-w-lg mt-6 rounded-md">
<div className="flex flex-row items-center"><FontAwesomeIcon icon={faCircleInfo} className="text-mineshaft-200 text-xl"/> <span className="ml-3 text-md text-mineshaft-100">Pro Tips</span></div>
<span className="text-mineshaft-300 text-sm mt-4">After creating an integration, your secrets will start syncing immediately. This might cause an unexpected override of current secrets in AWS Parameter Store with secrets from Infisical.</span>
<div className="mt-6 w-full max-w-md border-t border-mineshaft-800" />
<div className="mt-6 flex w-full max-w-lg flex-col rounded-md border border-mineshaft-600 bg-mineshaft-800 p-4">
<div className="flex flex-row items-center">
<FontAwesomeIcon icon={faCircleInfo} className="text-xl text-mineshaft-200" />{" "}
<span className="text-md ml-3 text-mineshaft-100">Pro Tips</span>
</div>
<span className="mt-4 text-sm text-mineshaft-300">
After creating an integration, your secrets will start syncing immediately. This might
cause an unexpected override of current secrets in AWS Parameter Store with secrets from
Infisical.
</span>
</div>
</div>
) : (
<div className="flex justify-center items-center w-full h-full">
<div className="flex h-full w-full items-center justify-center">
<Head>
<title>Set Up AWS Parameter Store Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
{isintegrationAuthLoading ? <img src="/images/loading/loading.gif" height={70} width={120} alt="infisical loading indicator" /> : <div className="max-w-md h-max p-6 border border-mineshaft-600 rounded-md bg-mineshaft-800 text-mineshaft-200 flex flex-col text-center">
<FontAwesomeIcon icon={faBugs} className="text-6xl my-2 inlineli"/>
<p>
Something went wrong. Please contact <a
className="inline underline underline-offset-4 decoration-primary-500 opacity-80 hover:opacity-100 text-mineshaft-100 duration-200 cursor-pointer"
target="_blank"
rel="noopener noreferrer"
href="mailto:[email protected]"
>
support@infisical.com
</a> if the issue persists.
</p>
</div>}
{isintegrationAuthLoading ? (
<img
src="/images/loading/loading.gif"
height={70}
width={120}
alt="infisical loading indicator"
/>
) : (
<div className="flex h-max max-w-md flex-col rounded-md border border-mineshaft-600 bg-mineshaft-800 p-6 text-center text-mineshaft-200">
<FontAwesomeIcon icon={faBugs} className="inlineli my-2 text-6xl" />
<p>
Something went wrong. Please contact{" "}
<a
className="inline cursor-pointer text-mineshaft-100 underline decoration-primary-500 underline-offset-4 opacity-80 duration-200 hover:opacity-100"
target="_blank"
rel="noopener noreferrer"
href="mailto:[email protected]"
>
support@infisical.com
</a>{" "}
if the issue persists.
</p>
</div>
)}
</div>
);
}
@@ -61,11 +61,11 @@ export default function AWSSecretManagerCreateIntegrationPage() {
<div className="flex h-full w-full items-center justify-center">
<Head>
<title>Authorize AWS Secrets Manager Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
<Card className="max-w-lg rounded-md border border-mineshaft-600">
<CardTitle
className="text-left px-6 text-xl"
<CardTitle
className="px-6 text-left text-xl"
subTitle="After adding the details below, you will be prompted to set up an integration for a particular Infisical project and environment."
>
<div className="flex flex-row items-center">
@@ -80,10 +80,13 @@ export default function AWSSecretManagerCreateIntegrationPage() {
<span className="ml-1.5">AWS Secrets Manager Integration </span>
<Link href="https://infisical.com/docs/integrations/cloud/aws-secret-manager" passHref>
<a target="_blank" rel="noopener noreferrer">
<div className="ml-2 mb-1 rounded-md text-yellow text-sm inline-block bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] opacity-80 hover:opacity-100 cursor-default">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5"/>
<div className="ml-2 mb-1 inline-block cursor-default rounded-md bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] text-sm text-yellow opacity-80 hover:opacity-100">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
Docs
<FontAwesomeIcon icon={faArrowUpRightFromSquare} className="ml-1.5 text-xxs mb-[0.07rem]"/>
<FontAwesomeIcon
icon={faArrowUpRightFromSquare}
className="ml-1.5 mb-[0.07rem] text-xxs"
/>
</div>
</a>
</Link>
@@ -3,13 +3,16 @@ import Head from "next/head";
import Image from "next/image";
import Link from "next/link";
import { useRouter } from "next/router";
import { faArrowUpRightFromSquare, faBookOpen, faBugs, faCircleInfo } from "@fortawesome/free-solid-svg-icons";
import {
faArrowUpRightFromSquare,
faBookOpen,
faBugs,
faCircleInfo
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import queryString from "query-string";
import {
useCreateIntegration
} from "@app/hooks/api";
import { useCreateIntegration } from "@app/hooks/api";
import {
Button,
@@ -62,7 +65,9 @@ export default function AWSSecretManagerCreateIntegrationPage() {
const { integrationAuthId } = queryString.parse(router.asPath.split("?")[1]);
const { data: workspace } = useGetWorkspaceById(localStorage.getItem("projectData.id") ?? "");
const { data: integrationAuth, isLoading: isintegrationAuthLoading } = useGetIntegrationAuthById((integrationAuthId as string) ?? "");
const { data: integrationAuth, isLoading: isintegrationAuthLoading } = useGetIntegrationAuthById(
(integrationAuthId as string) ?? ""
);
const [selectedSourceEnvironment, setSelectedSourceEnvironment] = useState("");
const [secretPath, setSecretPath] = useState("/");
@@ -117,14 +122,14 @@ export default function AWSSecretManagerCreateIntegrationPage() {
};
return integrationAuth && workspace && selectedSourceEnvironment ? (
<div className="flex flex-col h-full w-full items-center justify-center">
<div className="flex h-full w-full flex-col items-center justify-center">
<Head>
<title>Set Up AWS Secrets Manager Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
<Card className="max-w-lg rounded-md border border-mineshaft-600">
<CardTitle
className="text-left px-6 text-xl"
<CardTitle
className="px-6 text-left text-xl"
subTitle="Choose which environment in Infisical you want to sync to secerts in AWS Secrets Manager."
>
<div className="flex flex-row items-center">
@@ -139,10 +144,13 @@ export default function AWSSecretManagerCreateIntegrationPage() {
<span className="ml-1.5">AWS Secrets Manager Integration </span>
<Link href="https://infisical.com/docs/integrations/cloud/aws-secret-manager" passHref>
<a target="_blank" rel="noopener noreferrer">
<div className="ml-2 mb-1 rounded-md text-yellow text-sm inline-block bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] opacity-80 hover:opacity-100 cursor-default">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5"/>
<div className="ml-2 mb-1 inline-block cursor-default rounded-md bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] text-sm text-yellow opacity-80 hover:opacity-100">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
Docs
<FontAwesomeIcon icon={faArrowUpRightFromSquare} className="ml-1.5 text-xxs mb-[0.07rem]"/>
<FontAwesomeIcon
icon={faArrowUpRightFromSquare}
className="ml-1.5 mb-[0.07rem] text-xxs"
/>
</div>
</a>
</Link>
@@ -208,31 +216,49 @@ export default function AWSSecretManagerCreateIntegrationPage() {
Create Integration
</Button>
</Card>
<div className="border-t border-mineshaft-800 w-full max-w-md mt-6"/>
<div className="flex flex-col bg-mineshaft-800 border border-mineshaft-600 w-full p-4 max-w-lg mt-6 rounded-md">
<div className="flex flex-row items-center"><FontAwesomeIcon icon={faCircleInfo} className="text-mineshaft-200 text-xl"/> <span className="ml-3 text-md text-mineshaft-100">Pro Tips</span></div>
<span className="text-mineshaft-300 text-sm mt-4">After creating an integration, your secrets will start syncing immediately. This might cause an unexpected override of current secrets in AWS Secrets Manager with secrets from Infisical.</span>
<div className="mt-6 w-full max-w-md border-t border-mineshaft-800" />
<div className="mt-6 flex w-full max-w-lg flex-col rounded-md border border-mineshaft-600 bg-mineshaft-800 p-4">
<div className="flex flex-row items-center">
<FontAwesomeIcon icon={faCircleInfo} className="text-xl text-mineshaft-200" />{" "}
<span className="text-md ml-3 text-mineshaft-100">Pro Tips</span>
</div>
<span className="mt-4 text-sm text-mineshaft-300">
After creating an integration, your secrets will start syncing immediately. This might
cause an unexpected override of current secrets in AWS Secrets Manager with secrets from
Infisical.
</span>
</div>
</div>
) : (
<div className="flex justify-center items-center w-full h-full">
<div className="flex h-full w-full items-center justify-center">
<Head>
<title>Set Up AWS Secrets Manager Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
{isintegrationAuthLoading ? <img src="/images/loading/loading.gif" height={70} width={120} alt="infisical loading indicator" /> : <div className="max-w-md h-max p-6 border border-mineshaft-600 rounded-md bg-mineshaft-800 text-mineshaft-200 flex flex-col text-center">
<FontAwesomeIcon icon={faBugs} className="text-6xl my-2 inlineli"/>
<p>
Something went wrong. Please contact <a
className="inline underline underline-offset-4 decoration-primary-500 opacity-80 hover:opacity-100 text-mineshaft-100 duration-200 cursor-pointer"
target="_blank"
rel="noopener noreferrer"
href="mailto:[email protected]"
>
support@infisical.com
</a> if the issue persists.
</p>
</div>}
{isintegrationAuthLoading ? (
<img
src="/images/loading/loading.gif"
height={70}
width={120}
alt="infisical loading indicator"
/>
) : (
<div className="flex h-max max-w-md flex-col rounded-md border border-mineshaft-600 bg-mineshaft-800 p-6 text-center text-mineshaft-200">
<FontAwesomeIcon icon={faBugs} className="inlineli my-2 text-6xl" />
<p>
Something went wrong. Please contact{" "}
<a
className="inline cursor-pointer text-mineshaft-100 underline decoration-primary-500 underline-offset-4 opacity-80 duration-200 hover:opacity-100"
target="_blank"
rel="noopener noreferrer"
href="mailto:[email protected]"
>
support@infisical.com
</a>{" "}
if the issue persists.
</p>
</div>
)}
</div>
);
}
@@ -2,9 +2,7 @@ import { useEffect, useState } from "react";
import { useRouter } from "next/router";
import queryString from "query-string";
import {
useCreateIntegration
} from "@app/hooks/api";
import { useCreateIntegration } from "@app/hooks/api";
import {
Button,
@@ -2,9 +2,7 @@ import { useEffect } from "react";
import { useRouter } from "next/router";
import queryString from "query-string";
import {
useAuthorizeIntegration
} from "@app/hooks/api";
import { useAuthorizeIntegration } from "@app/hooks/api";
export default function AzureKeyVaultOAuth2CallbackPage() {
const router = useRouter();
@@ -25,9 +23,7 @@ export default function AzureKeyVaultOAuth2CallbackPage() {
integration: "azure-key-vault"
});
router.push(
`/integrations/azure-key-vault/create?integrationAuthId=${integrationAuth.id}`
);
router.push(`/integrations/azure-key-vault/create?integrationAuthId=${integrationAuth.id}`);
} catch (err) {
console.error(err);
}
@@ -2,9 +2,7 @@ import { useEffect, useState } from "react";
import { useRouter } from "next/router";
import queryString from "query-string";
import {
useCreateIntegration
} from "@app/hooks/api";
import { useCreateIntegration } from "@app/hooks/api";
import {
Button,
@@ -18,7 +16,7 @@ import {
import {
useGetIntegrationAuthApps,
useGetIntegrationAuthBitBucketWorkspaces,
useGetIntegrationAuthById,
useGetIntegrationAuthById
} from "../../../hooks/api/integrationAuth";
import { useGetWorkspaceById } from "../../../hooks/api/workspace";
@@ -36,7 +34,9 @@ export default function BitBucketCreateIntegrationPage() {
const { integrationAuthId } = queryString.parse(router.asPath.split("?")[1]);
const { data: integrationAuth } = useGetIntegrationAuthById((integrationAuthId as string) ?? "");
const { data: workspace } = useGetWorkspaceById(localStorage.getItem("projectData.id") ?? "");
const { data: targetEnvironments } = useGetIntegrationAuthBitBucketWorkspaces((integrationAuthId as string) ?? "");
const { data: targetEnvironments } = useGetIntegrationAuthBitBucketWorkspaces(
(integrationAuthId as string) ?? ""
);
const { data: integrationAuthApps } = useGetIntegrationAuthApps({
integrationAuthId: (integrationAuthId as string) ?? "",
workspaceSlug: targetEnvironmentId
@@ -2,9 +2,7 @@ import { useEffect } from "react";
import { useRouter } from "next/router";
import queryString from "query-string";
import {
useAuthorizeIntegration
} from "@app/hooks/api";
import { useAuthorizeIntegration } from "@app/hooks/api";
export default function BitBucketOAuth2CallbackPage() {
const router = useRouter();
@@ -6,9 +6,7 @@ import { useRouter } from "next/router";
import { faArrowUpRightFromSquare, faBookOpen } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
useSaveIntegrationAccessToken
} from "@app/hooks/api";
import { useSaveIntegrationAccessToken } from "@app/hooks/api";
import { Button, Card, CardTitle, FormControl, Input } from "../../../components/v2";
@@ -48,11 +46,11 @@ export default function ChecklyCreateIntegrationPage() {
<div className="flex h-full w-full items-center justify-center">
<Head>
<title>Authorize Checkly Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
<Card className="max-w-lg rounded-md border border-mineshaft-600 mb-12">
<CardTitle
className="text-left px-6 text-xl"
<Card className="mb-12 max-w-lg rounded-md border border-mineshaft-600">
<CardTitle
className="px-6 text-left text-xl"
subTitle="After adding your API key, you will be prompted to set up an integration for a particular Infisical project and environment."
>
<div className="flex flex-row items-center">
@@ -67,10 +65,13 @@ export default function ChecklyCreateIntegrationPage() {
<span className="ml-2.5">Checkly Integration </span>
<Link href="https://infisical.com/docs/integrations/cloud/checkly" passHref>
<a target="_blank" rel="noopener noreferrer">
<div className="ml-2 mb-1 rounded-md text-yellow text-sm inline-block bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] opacity-80 hover:opacity-100 cursor-default">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5"/>
<div className="ml-2 mb-1 inline-block cursor-default rounded-md bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] text-sm text-yellow opacity-80 hover:opacity-100">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
Docs
<FontAwesomeIcon icon={faArrowUpRightFromSquare} className="ml-1.5 text-xxs mb-[0.07rem]"/>
<FontAwesomeIcon
icon={faArrowUpRightFromSquare}
className="ml-1.5 mb-[0.07rem] text-xxs"
/>
</div>
</a>
</Link>
@@ -21,9 +21,7 @@ import {
TabPanel,
Tabs
} from "@app/components/v2";
import {
useCreateIntegration
} from "@app/hooks/api";
import { useCreateIntegration } from "@app/hooks/api";
import {
useGetIntegrationAuthApps,
@@ -54,13 +52,15 @@ export default function ChecklyCreateIntegrationPage() {
const { data: workspace } = useGetWorkspaceById(localStorage.getItem("projectData.id") ?? "");
const { data: integrationAuth } = useGetIntegrationAuthById((integrationAuthId as string) ?? "");
const { data: integrationAuthApps, isLoading: isIntegrationAuthAppsLoading } = useGetIntegrationAuthApps({
integrationAuthId: (integrationAuthId as string) ?? ""
});
const { data: integrationAuthGroups, isLoading: isintegrationAuthGroupsLoading } = useGetIntegrationAuthChecklyGroups({
integrationAuthId: (integrationAuthId as string) ?? "",
accountId: targetAppId
});
const { data: integrationAuthApps, isLoading: isIntegrationAuthAppsLoading } =
useGetIntegrationAuthApps({
integrationAuthId: (integrationAuthId as string) ?? ""
});
const { data: integrationAuthGroups, isLoading: isintegrationAuthGroupsLoading } =
useGetIntegrationAuthChecklyGroups({
integrationAuthId: (integrationAuthId as string) ?? "",
accountId: targetAppId
});
useEffect(() => {
if (workspace) {
@@ -90,9 +90,9 @@ export default function ChecklyCreateIntegrationPage() {
const targetGroup = integrationAuthGroups?.find(
(group) => group.groupId === Number(targetGroupId)
);
if (!targetApp) return;
await mutateAsync({
integrationAuthId: integrationAuth?.id,
isActive: true,
@@ -118,17 +118,17 @@ export default function ChecklyCreateIntegrationPage() {
return integrationAuth &&
workspace &&
selectedSourceEnvironment &&
integrationAuthApps &&
integrationAuthApps &&
integrationAuthGroups &&
targetAppId ? (
<div className="flex h-full flex-col w-full py-6 items-center justify-center bg-gradient-to-tr from-mineshaft-900 to-bunker-900">
<div className="flex h-full w-full flex-col items-center justify-center bg-gradient-to-tr from-mineshaft-900 to-bunker-900 py-6">
<Head>
<title>Set Up Checkly Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
<Card className="max-w-lg rounded-md border border-mineshaft-600 p-0">
<CardTitle
className="text-left px-6 text-xl"
<CardTitle
className="px-6 text-left text-xl"
subTitle="Choose which environment in Infisical you want to sync to Checkly environment variables."
>
<div className="flex flex-row items-center">
@@ -143,10 +143,13 @@ export default function ChecklyCreateIntegrationPage() {
<span className="ml-2.5">Checkly Integration </span>
<Link href="https://infisical.com/docs/integrations/cloud/checkly" passHref>
<a target="_blank" rel="noopener noreferrer">
<div className="ml-2 mb-1 rounded-md text-yellow text-sm inline-block bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] opacity-80 hover:opacity-100 cursor-default">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5"/>
<div className="ml-2 mb-1 inline-block cursor-default rounded-md bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] text-sm text-yellow opacity-80 hover:opacity-100">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
Docs
<FontAwesomeIcon icon={faArrowUpRightFromSquare} className="ml-1.5 text-xxs mb-[0.07rem]"/>
<FontAwesomeIcon
icon={faArrowUpRightFromSquare}
className="ml-1.5 mb-[0.07rem] text-xxs"
/>
</div>
</a>
</Link>
@@ -154,7 +157,7 @@ export default function ChecklyCreateIntegrationPage() {
</CardTitle>
<Tabs defaultValue={TabSections.Connection} className="px-6">
<TabList>
<div className="flex flex-row border-b border-mineshaft-600 w-full">
<div className="flex w-full flex-row border-b border-mineshaft-600">
<Tab value={TabSections.Connection}>Connection</Tab>
<Tab value={TabSections.Options}>Options</Tab>
</div>
@@ -268,24 +271,35 @@ export default function ChecklyCreateIntegrationPage() {
</Card>
</div>
) : (
<div className="flex justify-center items-center w-full h-full">
<div className="flex h-full w-full items-center justify-center">
<Head>
<title>Set Up Checkly Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
{isIntegrationAuthAppsLoading || isintegrationAuthGroupsLoading ? <img src="/images/loading/loading.gif" height={70} width={120} alt="infisical loading indicator" /> : <div className="max-w-md h-max p-6 border border-mineshaft-600 rounded-md bg-mineshaft-800 text-mineshaft-200 flex flex-col text-center">
<FontAwesomeIcon icon={faBugs} className="text-6xl my-2 inlineli"/>
<p>
Something went wrong. Please contact <a
className="inline underline underline-offset-4 decoration-primary-500 opacity-80 hover:opacity-100 text-mineshaft-100 duration-200 cursor-pointer"
target="_blank"
rel="noopener noreferrer"
href="mailto:[email protected]"
>
support@infisical.com
</a> if the issue persists.
</p>
</div>}
{isIntegrationAuthAppsLoading || isintegrationAuthGroupsLoading ? (
<img
src="/images/loading/loading.gif"
height={70}
width={120}
alt="infisical loading indicator"
/>
) : (
<div className="flex h-max max-w-md flex-col rounded-md border border-mineshaft-600 bg-mineshaft-800 p-6 text-center text-mineshaft-200">
<FontAwesomeIcon icon={faBugs} className="inlineli my-2 text-6xl" />
<p>
Something went wrong. Please contact{" "}
<a
className="inline cursor-pointer text-mineshaft-100 underline decoration-primary-500 underline-offset-4 opacity-80 duration-200 hover:opacity-100"
target="_blank"
rel="noopener noreferrer"
href="mailto:[email protected]"
>
support@infisical.com
</a>{" "}
if the issue persists.
</p>
</div>
)}
</div>
);
}
@@ -6,9 +6,7 @@ import { useRouter } from "next/router";
import { faArrowUpRightFromSquare, faBookOpen } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
useSaveIntegrationAccessToken
} from "@app/hooks/api";
import { useSaveIntegrationAccessToken } from "@app/hooks/api";
import { Button, Card, CardTitle, FormControl, Input } from "../../../components/v2";
@@ -48,11 +46,11 @@ export default function CircleCICreateIntegrationPage() {
<div className="flex h-full w-full items-center justify-center">
<Head>
<title>Authorize CircleCI Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
<Card className="max-w-lg rounded-md border border-mineshaft-600 mb-12">
<CardTitle
className="text-left px-6 text-xl"
<Card className="mb-12 max-w-lg rounded-md border border-mineshaft-600">
<CardTitle
className="px-6 text-left text-xl"
subTitle="After adding your API Token, you will be prompted to set up an integration for a particular Infisical project and environment."
>
<div className="flex flex-row items-center">
@@ -67,10 +65,13 @@ export default function CircleCICreateIntegrationPage() {
<span className="ml-1.5">CircleCI Integration </span>
<Link href="https://infisical.com/docs/integrations/cicd/circleci" passHref>
<a target="_blank" rel="noopener noreferrer">
<div className="ml-2 mb-1 rounded-md text-yellow text-sm inline-block bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] opacity-80 hover:opacity-100 cursor-default">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5"/>
<div className="ml-2 mb-1 inline-block cursor-default rounded-md bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] text-sm text-yellow opacity-80 hover:opacity-100">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
Docs
<FontAwesomeIcon icon={faArrowUpRightFromSquare} className="ml-1.5 text-xxs mb-[0.07rem]"/>
<FontAwesomeIcon
icon={faArrowUpRightFromSquare}
className="ml-1.5 mb-[0.07rem] text-xxs"
/>
</div>
</a>
</Link>
@@ -3,13 +3,16 @@ import Head from "next/head";
import Image from "next/image";
import Link from "next/link";
import { useRouter } from "next/router";
import { faArrowUpRightFromSquare, faBookOpen, faBugs, faCircleInfo } from "@fortawesome/free-solid-svg-icons";
import {
faArrowUpRightFromSquare,
faBookOpen,
faBugs,
faCircleInfo
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import queryString from "query-string";
import {
useCreateIntegration
} from "@app/hooks/api";
import { useCreateIntegration } from "@app/hooks/api";
import {
Button,
@@ -33,10 +36,13 @@ export default function CircleCICreateIntegrationPage() {
const { integrationAuthId } = queryString.parse(router.asPath.split("?")[1]);
const { data: workspace } = useGetWorkspaceById(localStorage.getItem("projectData.id") ?? "");
const { data: integrationAuth, isLoading: isintegrationAuthLoading } = useGetIntegrationAuthById((integrationAuthId as string) ?? "");
const { data: integrationAuthApps, isLoading: isIntegrationAuthAppsLoading } = useGetIntegrationAuthApps({
integrationAuthId: (integrationAuthId as string) ?? ""
});
const { data: integrationAuth, isLoading: isintegrationAuthLoading } = useGetIntegrationAuthById(
(integrationAuthId as string) ?? ""
);
const { data: integrationAuthApps, isLoading: isIntegrationAuthAppsLoading } =
useGetIntegrationAuthApps({
integrationAuthId: (integrationAuthId as string) ?? ""
});
const [selectedSourceEnvironment, setSelectedSourceEnvironment] = useState("");
const [secretPath, setSecretPath] = useState("/");
@@ -71,7 +77,9 @@ export default function CircleCICreateIntegrationPage() {
integrationAuthId: integrationAuth?.id,
isActive: true,
app: targetApp,
appId: integrationAuthApps?.find((integrationAuthApp) => integrationAuthApp.name === targetApp)?.appId,
appId: integrationAuthApps?.find(
(integrationAuthApp) => integrationAuthApp.name === targetApp
)?.appId,
sourceEnvironment: selectedSourceEnvironment,
secretPath
});
@@ -89,14 +97,14 @@ export default function CircleCICreateIntegrationPage() {
selectedSourceEnvironment &&
integrationAuthApps &&
targetApp ? (
<div className="flex flex-col h-full w-full items-center justify-center">
<div className="flex h-full w-full flex-col items-center justify-center">
<Head>
<title>Set Up CircleCI Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
<Card className="max-w-lg rounded-md border border-mineshaft-600">
<CardTitle
className="text-left px-6 text-xl"
<CardTitle
className="px-6 text-left text-xl"
subTitle="Choose which environment or folder in Infisical you want to sync to CircleCI environment variables."
>
<div className="flex flex-row items-center">
@@ -111,10 +119,13 @@ export default function CircleCICreateIntegrationPage() {
<span className="ml-1.5">CircleCI Integration </span>
<Link href="https://infisical.com/docs/integrations/cicd/circleci" passHref>
<a target="_blank" rel="noopener noreferrer">
<div className="ml-2 mb-1 rounded-md text-yellow text-sm inline-block bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] opacity-80 hover:opacity-100 cursor-default">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5"/>
<div className="ml-2 mb-1 inline-block cursor-default rounded-md bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] text-sm text-yellow opacity-80 hover:opacity-100">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
Docs
<FontAwesomeIcon icon={faArrowUpRightFromSquare} className="ml-1.5 text-xxs mb-[0.07rem]"/>
<FontAwesomeIcon
icon={faArrowUpRightFromSquare}
className="ml-1.5 mb-[0.07rem] text-xxs"
/>
</div>
</a>
</Link>
@@ -177,31 +188,48 @@ export default function CircleCICreateIntegrationPage() {
Create Integration
</Button>
</Card>
<div className="border-t border-mineshaft-800 w-full max-w-md mt-6"/>
<div className="flex flex-col bg-mineshaft-800 border border-mineshaft-600 w-full p-4 max-w-lg mt-6 rounded-md">
<div className="flex flex-row items-center"><FontAwesomeIcon icon={faCircleInfo} className="text-mineshaft-200 text-xl"/> <span className="ml-3 text-md text-mineshaft-100">Pro Tips</span></div>
<span className="text-mineshaft-300 text-sm mt-4">After creating an integration, your secrets will start syncing immediately. This might cause an unexpected override of current secrets in CircleCI with secrets from Infisical.</span>
<div className="mt-6 w-full max-w-md border-t border-mineshaft-800" />
<div className="mt-6 flex w-full max-w-lg flex-col rounded-md border border-mineshaft-600 bg-mineshaft-800 p-4">
<div className="flex flex-row items-center">
<FontAwesomeIcon icon={faCircleInfo} className="text-xl text-mineshaft-200" />{" "}
<span className="text-md ml-3 text-mineshaft-100">Pro Tips</span>
</div>
<span className="mt-4 text-sm text-mineshaft-300">
After creating an integration, your secrets will start syncing immediately. This might
cause an unexpected override of current secrets in CircleCI with secrets from Infisical.
</span>
</div>
</div>
) : (
<div className="flex justify-center items-center w-full h-full">
<div className="flex h-full w-full items-center justify-center">
<Head>
<title>Set Up CircleCI Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
{isIntegrationAuthAppsLoading || isintegrationAuthLoading ? <img src="/images/loading/loading.gif" height={70} width={120} alt="infisical loading indicator" /> : <div className="max-w-md h-max p-6 border border-mineshaft-600 rounded-md bg-mineshaft-800 text-mineshaft-200 flex flex-col text-center">
<FontAwesomeIcon icon={faBugs} className="text-6xl my-2 inlineli"/>
<p>
Something went wrong. Please contact <a
className="inline underline underline-offset-4 decoration-primary-500 opacity-80 hover:opacity-100 text-mineshaft-100 duration-200 cursor-pointer"
target="_blank"
rel="noopener noreferrer"
href="mailto:[email protected]"
>
support@infisical.com
</a> if the issue persists.
</p>
</div>}
{isIntegrationAuthAppsLoading || isintegrationAuthLoading ? (
<img
src="/images/loading/loading.gif"
height={70}
width={120}
alt="infisical loading indicator"
/>
) : (
<div className="flex h-max max-w-md flex-col rounded-md border border-mineshaft-600 bg-mineshaft-800 p-6 text-center text-mineshaft-200">
<FontAwesomeIcon icon={faBugs} className="inlineli my-2 text-6xl" />
<p>
Something went wrong. Please contact{" "}
<a
className="inline cursor-pointer text-mineshaft-100 underline decoration-primary-500 underline-offset-4 opacity-80 duration-200 hover:opacity-100"
target="_blank"
rel="noopener noreferrer"
href="mailto:[email protected]"
>
support@infisical.com
</a>{" "}
if the issue persists.
</p>
</div>
)}
</div>
);
}
@@ -1,9 +1,7 @@
import { useState } from "react";
import { useRouter } from "next/router";
import {
useSaveIntegrationAccessToken
} from "@app/hooks/api";
import { useSaveIntegrationAccessToken } from "@app/hooks/api";
import { Button, Card, CardTitle, FormControl, Input } from "../../../components/v2";
@@ -2,9 +2,7 @@ import { useEffect, useState } from "react";
import { useRouter } from "next/router";
import queryString from "query-string";
import {
useCreateIntegration
} from "@app/hooks/api";
import { useCreateIntegration } from "@app/hooks/api";
import {
Button,
@@ -16,8 +14,8 @@ import {
SelectItem
} from "../../../components/v2";
import {
useGetIntegrationAuthApps,
useGetIntegrationAuthById,
useGetIntegrationAuthApps,
useGetIntegrationAuthById
} from "../../../hooks/api/integrationAuth";
import { useGetWorkspaceById } from "../../../hooks/api/workspace";
@@ -64,7 +62,9 @@ export default function Cloud66CreateIntegrationPage() {
integrationAuthId: integrationAuth?.id,
isActive: true,
app: targetApp,
appId: integrationAuthApps?.find((integrationAuthApp) => integrationAuthApp.name === targetApp)?.appId,
appId: integrationAuthApps?.find(
(integrationAuthApp) => integrationAuthApp.name === targetApp
)?.appId,
sourceEnvironment: selectedSourceEnvironment,
secretPath
});
@@ -1,92 +1,102 @@
import { useState } from "react";
import Head from "next/head";
import Image from "next/image";
import Link from "next/link";
import { useRouter } from "next/router";
import { faArrowUpRightFromSquare, faBookOpen } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
useSaveIntegrationAccessToken
} from "@app/hooks/api";
import { useSaveIntegrationAccessToken } from "@app/hooks/api";
import { Button,Card, CardTitle, FormControl, Input } from "../../../components/v2";
import { Button, Card, CardTitle, FormControl, Input } from "../../../components/v2";
export default function CloudflarePagesIntegrationPage() {
const router = useRouter();
const { mutateAsync } = useSaveIntegrationAccessToken();
export default function RenderCreateIntegrationPage() {
const router = useRouter();
const { mutateAsync } = useSaveIntegrationAccessToken();
const [accessKey, setAccessKey] = useState("");
const [accessKeyErrorText, setAccessKeyErrorText] = useState("");
const [accountId, setAccountId] = useState("");
const [accountIdErrorText, setAccountIdErrorText] = useState("");
const [isLoading, setIsLoading] = useState(false);
const [apiKey, setApiKey] = useState("");
const [apiKeyErrorText, setApiKeyErrorText] = useState("");
const [isLoading, setIsLoading] = useState(false);
const handleButtonClick = async () => {
try {
setAccessKeyErrorText("");
setAccountIdErrorText("");
if (accessKey.length === 0 || accountId.length === 0) {
if (accessKey.length === 0) setAccessKeyErrorText("API token cannot be blank!");
if (accountId.length === 0) setAccountIdErrorText("Account ID cannot be blank!");
return;
}
const handleButtonClick = async () => {
try {
setApiKeyErrorText("");
if (apiKey.length === 0) {
setApiKeyErrorText("API Key cannot be blank");
return;
}
setIsLoading(true);
setIsLoading(true);
const integrationAuth = await mutateAsync({
workspaceId: localStorage.getItem("projectData.id"),
integration: "cloudflare-pages",
accessId: accountId,
accessToken: accessKey
});
const integrationAuth = await mutateAsync({
workspaceId: localStorage.getItem("projectData.id"),
integration: "render",
accessToken: apiKey
});
setAccessKey("");
setAccountId("");
setIsLoading(false);
setIsLoading(false);
router.push(`/integrations/cloudflare-pages/create?integrationAuthId=${integrationAuth.id}`);
} catch (err) {
console.error(err);
}
router.push(`/integrations/render/create?integrationAuthId=${integrationAuth._id}`);
} catch (err) {
console.error(err);
}
};
return (
<div className="flex h-full w-full items-center justify-center">
<Card className="max-w-lg rounded-md border border-mineshaft-600 mb-12">
<CardTitle className="text-left px-6" subTitle="After adding your API-key, you will be prompted to set up an integration for a particular Infisical project and environment.">Cloudflare Pages Integration</CardTitle>
<FormControl
label="Cloudflare Pages API token"
errorText={accessKeyErrorText}
isError={accessKeyErrorText !== "" ?? false}
className="mx-6"
>
<Input
placeholder=""
value={accessKey}
onChange={(e) => setAccessKey(e.target.value)}
/>
</FormControl>
<FormControl
label="Cloudflare Pages Account ID"
errorText={accountIdErrorText}
isError={accountIdErrorText !== "" ?? false}
className="mx-6"
>
<Input
placeholder=""
value={accountId}
onChange={(e) => setAccountId(e.target.value)}
/>
</FormControl>
<Button
onClick={handleButtonClick}
color="mineshaft"
variant="outline_bg"
className="mb-6 mt-2 ml-auto mr-6 w-min"
isFullWidth={false}
isLoading={isLoading}
>
Connect to Cloudflare Pages
</Button>
</Card>
</div>
);
return (
<div className="flex h-full w-full items-center justify-center">
<Head>
<title>Authorize Render Integration</title>
<link rel="icon" href="/infisical.ico" />
</Head>
<Card className="mb-12 max-w-lg rounded-md border border-mineshaft-600">
<CardTitle
className="px-6 text-left text-xl"
subTitle="After adding your API key, you will be prompted to set up an integration for a particular Infisical project and environment."
>
<div className="flex flex-row items-center">
<div className="inline flex items-center pb-0.5">
<Image
src="/images/integrations/Render.png"
height={30}
width={30}
alt="Render logo"
/>
</div>
<span className="ml-2.5">Render Integration </span>
<Link href="https://infisical.com/docs/integrations/cloud/render" passHref>
<a target="_blank" rel="noopener noreferrer">
<div className="ml-2 mb-1 inline-block cursor-default rounded-md bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] text-sm text-yellow opacity-80 hover:opacity-100">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
Docs
<FontAwesomeIcon
icon={faArrowUpRightFromSquare}
className="ml-1.5 mb-[0.07rem] text-xxs"
/>
</div>
</a>
</Link>
</div>
</CardTitle>
<FormControl
label="Render API Key"
errorText={apiKeyErrorText}
isError={apiKeyErrorText !== "" ?? false}
className="px-6"
>
<Input placeholder="rnd_xxx" value={apiKey} onChange={(e) => setApiKey(e.target.value)} />
</FormControl>
<Button
onClick={handleButtonClick}
colorSchema="primary"
variant="outline_bg"
className="mb-6 mt-2 ml-auto mr-6 w-min"
isLoading={isLoading}
>
Connect to Render
</Button>
</Card>
</div>
);
}
CloudflarePagesIntegrationPage.requireAuth = true;
RenderCreateIntegrationPage.requireAuth = true;
@@ -1,159 +1,165 @@
import { useEffect,useState } from "react";
import { useEffect, useState } from "react";
import { useRouter } from "next/router";
import queryString from "query-string";
import {
useCreateIntegration
, useGetWorkspaceById } from "@app/hooks/api";
import { useCreateIntegration, useGetWorkspaceById } from "@app/hooks/api";
import { Button, Card, CardTitle, FormControl, Select, SelectItem } from "../../../components/v2";
import { useGetIntegrationAuthApps, useGetIntegrationAuthById } from "../../../hooks/api/integrationAuth";
import {
useGetIntegrationAuthApps,
useGetIntegrationAuthById
} from "../../../hooks/api/integrationAuth";
const cloudflareEnvironments = [
{ name: "Production", slug: "production" },
{ name: "Preview", slug: "preview" }
{ name: "Production", slug: "production" },
{ name: "Preview", slug: "preview" }
];
export default function CloudflarePagesIntegrationPage() {
const router = useRouter();
const { mutateAsync } = useCreateIntegration();
const router = useRouter();
const { mutateAsync } = useCreateIntegration();
const { integrationAuthId } = queryString.parse(router.asPath.split("?")[1]);
const { data: workspace } = useGetWorkspaceById(localStorage.getItem("projectData.id") ?? "");
const { data: integrationAuth } = useGetIntegrationAuthById((integrationAuthId as string) ?? "");
const { data: integrationAuthApps } = useGetIntegrationAuthApps({
integrationAuthId: (integrationAuthId as string) ?? ""
});
const { integrationAuthId } = queryString.parse(router.asPath.split("?")[1]);
const { data: workspace } = useGetWorkspaceById(localStorage.getItem("projectData.id") ?? "");
const { data: integrationAuth } = useGetIntegrationAuthById((integrationAuthId as string) ?? "");
const { data: integrationAuthApps } = useGetIntegrationAuthApps({
integrationAuthId: (integrationAuthId as string) ?? ""
});
const [selectedSourceEnvironment, setSelectedSourceEnvironment] = useState("");
const [targetApp, setTargetApp] = useState("");
const [targetAppId, setTargetAppId] = useState("");
const [targetEnvironment, setTargetEnvironment] = useState("");
const [selectedSourceEnvironment, setSelectedSourceEnvironment] = useState("");
const [targetApp, setTargetApp] = useState("");
const [targetAppId, setTargetAppId] = useState("");
const [targetEnvironment, setTargetEnvironment] = useState("");
const [isLoading, setIsLoading] = useState(false);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
if (workspace) {
setSelectedSourceEnvironment(workspace.environments[0].slug);
}
}, [workspace]);
useEffect(() => {
if (integrationAuthApps) {
if (integrationAuthApps.length > 0) {
setTargetApp(integrationAuthApps[0].name);
setTargetAppId(String(integrationAuthApps[0].appId));
setTargetEnvironment(cloudflareEnvironments[0].slug);
} else {
setTargetApp("none");
setTargetEnvironment(cloudflareEnvironments[0].slug);
}
}
}, [integrationAuthApps]);
const handleButtonClick = async () => {
try {
if (!integrationAuth?.id) return;
setIsLoading(true);
await mutateAsync({
integrationAuthId: integrationAuth?.id,
isActive: true,
app: targetApp,
appId: targetAppId,
sourceEnvironment: selectedSourceEnvironment,
targetEnvironment,
secretPath: "/",
});
setIsLoading(false);
router.push(`/integrations/${localStorage.getItem("projectData.id")}`);
} catch(err) {
console.error(err);
}
useEffect(() => {
if (workspace) {
setSelectedSourceEnvironment(workspace.environments[0].slug);
}
}, [workspace]);
return integrationAuth &&
workspace &&
selectedSourceEnvironment &&
integrationAuthApps &&
targetEnvironment &&
targetApp ? (
<div className="flex h-full w-full items-center justify-center bg-gradient-to-tr from-mineshaft-900 to-bunker-900">
<Card className="max-w-lg rounded-md p-0 border border-mineshaft-600">
<CardTitle className="text-left px-6" subTitle="Choose which environment in Infisical you want to sync with your Cloudflare Pages project.">Cloudflare Pages Integration</CardTitle>
<FormControl label="Infisical Project Environment" className="mt-2 px-6">
<Select
value={selectedSourceEnvironment}
onValueChange={(val) => setSelectedSourceEnvironment(val)}
className="w-full border border-mineshaft-500"
>
{workspace?.environments.map((sourceEnvironment) => (
<SelectItem
value={sourceEnvironment.slug}
key={`source-environment-${sourceEnvironment.slug}`}
>
{sourceEnvironment.name}
</SelectItem>
))}
</Select>
</FormControl>
<FormControl label="Cloudflare Pages Project" className="mt-4 px-6">
<Select
value={targetApp}
onValueChange={(val) => setTargetApp(val)}
className="w-full border border-mineshaft-500"
isDisabled={integrationAuthApps.length === 0}
>
{integrationAuthApps.length > 0 ? (
integrationAuthApps.map((integrationAuthApp) => (
<SelectItem
value={integrationAuthApp.name}
key={`target-app-${integrationAuthApp.name}`}
>
{integrationAuthApp.name}
</SelectItem>
))
) : (
<SelectItem value="none" key="target-app-none">
No apps found
</SelectItem>
)}
</Select>
</FormControl>
<FormControl label="Cloudflare Pages Environment" className="mt-4 px-6">
<Select
value={targetEnvironment}
onValueChange={(val) => setTargetEnvironment(val)}
className="w-full border border-mineshaft-500"
>
{cloudflareEnvironments.map((cloudflareEnvironment) => (
<SelectItem
value={cloudflareEnvironment.slug}
key={`target-environment-${cloudflareEnvironment.slug}`}
>
{cloudflareEnvironment.name}
</SelectItem>
))}
</Select>
</FormControl>
<Button
onClick={handleButtonClick}
color="mineshaft"
variant="outline_bg"
className="mt-2 mb-6 ml-auto mr-6"
isFullWidth={false}
isLoading={isLoading}
useEffect(() => {
if (integrationAuthApps) {
if (integrationAuthApps.length > 0) {
setTargetApp(integrationAuthApps[0].name);
setTargetAppId(String(integrationAuthApps[0].appId));
setTargetEnvironment(cloudflareEnvironments[0].slug);
} else {
setTargetApp("none");
setTargetEnvironment(cloudflareEnvironments[0].slug);
}
}
}, [integrationAuthApps]);
const handleButtonClick = async () => {
try {
if (!integrationAuth?.id) return;
setIsLoading(true);
await mutateAsync({
integrationAuthId: integrationAuth?.id,
isActive: true,
app: targetApp,
appId: targetAppId,
sourceEnvironment: selectedSourceEnvironment,
targetEnvironment,
secretPath: "/"
});
setIsLoading(false);
router.push(`/integrations/${localStorage.getItem("projectData.id")}`);
} catch (err) {
console.error(err);
}
};
return integrationAuth &&
workspace &&
selectedSourceEnvironment &&
integrationAuthApps &&
targetEnvironment &&
targetApp ? (
<div className="flex h-full w-full items-center justify-center bg-gradient-to-tr from-mineshaft-900 to-bunker-900">
<Card className="max-w-lg rounded-md border border-mineshaft-600 p-0">
<CardTitle
className="px-6 text-left"
subTitle="Choose which environment in Infisical you want to sync with your Cloudflare Pages project."
>
Cloudflare Pages Integration
</CardTitle>
<FormControl label="Infisical Project Environment" className="mt-2 px-6">
<Select
value={selectedSourceEnvironment}
onValueChange={(val) => setSelectedSourceEnvironment(val)}
className="w-full border border-mineshaft-500"
>
{workspace?.environments.map((sourceEnvironment) => (
<SelectItem
value={sourceEnvironment.slug}
key={`source-environment-${sourceEnvironment.slug}`}
>
{sourceEnvironment.name}
</SelectItem>
))}
</Select>
</FormControl>
<FormControl label="Cloudflare Pages Project" className="mt-4 px-6">
<Select
value={targetApp}
onValueChange={(val) => setTargetApp(val)}
className="w-full border border-mineshaft-500"
isDisabled={integrationAuthApps.length === 0}
>
{integrationAuthApps.length > 0 ? (
integrationAuthApps.map((integrationAuthApp) => (
<SelectItem
value={integrationAuthApp.name}
key={`target-app-${integrationAuthApp.name}`}
>
Create Integration
</Button>
</Card>
</div>
) : (
<div />
);
{integrationAuthApp.name}
</SelectItem>
))
) : (
<SelectItem value="none" key="target-app-none">
No apps found
</SelectItem>
)}
</Select>
</FormControl>
<FormControl label="Cloudflare Pages Environment" className="mt-4 px-6">
<Select
value={targetEnvironment}
onValueChange={(val) => setTargetEnvironment(val)}
className="w-full border border-mineshaft-500"
>
{cloudflareEnvironments.map((cloudflareEnvironment) => (
<SelectItem
value={cloudflareEnvironment.slug}
key={`target-environment-${cloudflareEnvironment.slug}`}
>
{cloudflareEnvironment.name}
</SelectItem>
))}
</Select>
</FormControl>
<Button
onClick={handleButtonClick}
color="mineshaft"
variant="outline_bg"
className="mt-2 mb-6 ml-auto mr-6"
isFullWidth={false}
isLoading={isLoading}
>
Create Integration
</Button>
</Card>
</div>
) : (
<div />
);
}
CloudflarePagesIntegrationPage.requireAuth = true;
CloudflarePagesIntegrationPage.requireAuth = true;
@@ -1,92 +1,89 @@
import { useState } from "react";
import { useRouter } from "next/router";
import {
useSaveIntegrationAccessToken
} from "@app/hooks/api";
import { useSaveIntegrationAccessToken } from "@app/hooks/api";
import { Button,Card, CardTitle, FormControl, Input } from "../../../components/v2";
import { Button, Card, CardTitle, FormControl, Input } from "../../../components/v2";
export default function CloudflareWorkersIntegrationPage() {
const router = useRouter();
const { mutateAsync } = useSaveIntegrationAccessToken();
const router = useRouter();
const { mutateAsync } = useSaveIntegrationAccessToken();
const [accessKey, setAccessKey] = useState("");
const [accessKeyErrorText, setAccessKeyErrorText] = useState("");
const [accountId, setAccountId] = useState("");
const [accountIdErrorText, setAccountIdErrorText] = useState("");
const [isLoading, setIsLoading] = useState(false);
const [accessKey, setAccessKey] = useState("");
const [accessKeyErrorText, setAccessKeyErrorText] = useState("");
const [accountId, setAccountId] = useState("");
const [accountIdErrorText, setAccountIdErrorText] = useState("");
const [isLoading, setIsLoading] = useState(false);
const handleButtonClick = async () => {
try {
setAccessKeyErrorText("");
setAccountIdErrorText("");
if (accessKey.length === 0 || accountId.length === 0) {
if (accessKey.length === 0) setAccessKeyErrorText("API token cannot be blank!");
if (accountId.length === 0) setAccountIdErrorText("Account ID cannot be blank!");
return;
}
const handleButtonClick = async () => {
try {
setAccessKeyErrorText("");
setAccountIdErrorText("");
if (accessKey.length === 0 || accountId.length === 0) {
if (accessKey.length === 0) setAccessKeyErrorText("API token cannot be blank!");
if (accountId.length === 0) setAccountIdErrorText("Account ID cannot be blank!");
return;
}
setIsLoading(true);
setIsLoading(true);
const integrationAuth = await mutateAsync({
workspaceId: localStorage.getItem("projectData.id"),
integration: "cloudflare-workers",
accessId: accountId,
accessToken: accessKey
});
const integrationAuth = await mutateAsync({
workspaceId: localStorage.getItem("projectData.id"),
integration: "cloudflare-workers",
accessId: accountId,
accessToken: accessKey
});
setAccessKey("");
setAccountId("");
setIsLoading(false);
setAccessKey("");
setAccountId("");
setIsLoading(false);
router.push(`/integrations/cloudflare-workers/create?integrationAuthId=${integrationAuth.id}`);
} catch (err) {
console.error(err);
}
router.push(
`/integrations/cloudflare-workers/create?integrationAuthId=${integrationAuth.id}`
);
} catch (err) {
console.error(err);
}
};
return (
<div className="flex h-full w-full items-center justify-center">
<Card className="max-w-lg rounded-md border border-mineshaft-600 mb-12">
<CardTitle className="text-left px-6" subTitle="After adding your API-key, you will be prompted to set up an integration for a particular Infisical project and environment.">Cloudflare Workers Integration</CardTitle>
<FormControl
label="Cloudflare Workers API token"
errorText={accessKeyErrorText}
isError={accessKeyErrorText !== "" ?? false}
className="mx-6"
>
<Input
placeholder=""
value={accessKey}
onChange={(e) => setAccessKey(e.target.value)}
/>
</FormControl>
<FormControl
label="Cloudflare Workers Account ID"
errorText={accountIdErrorText}
isError={accountIdErrorText !== "" ?? false}
className="mx-6"
>
<Input
placeholder=""
value={accountId}
onChange={(e) => setAccountId(e.target.value)}
/>
</FormControl>
<Button
onClick={handleButtonClick}
color="mineshaft"
variant="outline_bg"
className="mb-6 mt-2 ml-auto mr-6 w-min"
isFullWidth={false}
isLoading={isLoading}
>
Connect to Cloudflare Workers
</Button>
</Card>
</div>
);
return (
<div className="flex h-full w-full items-center justify-center">
<Card className="mb-12 max-w-lg rounded-md border border-mineshaft-600">
<CardTitle
className="px-6 text-left"
subTitle="After adding your API-key, you will be prompted to set up an integration for a particular Infisical project and environment."
>
Cloudflare Workers Integration
</CardTitle>
<FormControl
label="Cloudflare Workers API token"
errorText={accessKeyErrorText}
isError={accessKeyErrorText !== "" ?? false}
className="mx-6"
>
<Input placeholder="" value={accessKey} onChange={(e) => setAccessKey(e.target.value)} />
</FormControl>
<FormControl
label="Cloudflare Workers Account ID"
errorText={accountIdErrorText}
isError={accountIdErrorText !== "" ?? false}
className="mx-6"
>
<Input placeholder="" value={accountId} onChange={(e) => setAccountId(e.target.value)} />
</FormControl>
<Button
onClick={handleButtonClick}
color="mineshaft"
variant="outline_bg"
className="mb-6 mt-2 ml-auto mr-6 w-min"
isFullWidth={false}
isLoading={isLoading}
>
Connect to Cloudflare Workers
</Button>
</Card>
</div>
);
}
CloudflareWorkersIntegrationPage.requireAuth = true;
CloudflareWorkersIntegrationPage.requireAuth = true;
@@ -1,133 +1,139 @@
import { useEffect,useState } from "react";
import { useEffect, useState } from "react";
import { useRouter } from "next/router";
import queryString from "query-string";
import {
useCreateIntegration
, useGetWorkspaceById } from "@app/hooks/api";
import { useCreateIntegration, useGetWorkspaceById } from "@app/hooks/api";
import { Button, Card, CardTitle, FormControl, Select, SelectItem } from "../../../components/v2";
import { useGetIntegrationAuthApps, useGetIntegrationAuthById } from "../../../hooks/api/integrationAuth";
import {
useGetIntegrationAuthApps,
useGetIntegrationAuthById
} from "../../../hooks/api/integrationAuth";
export default function CloudflareWorkersIntegrationPage() {
const router = useRouter();
const { mutateAsync } = useCreateIntegration();
const router = useRouter();
const { mutateAsync } = useCreateIntegration();
const { integrationAuthId } = queryString.parse(router.asPath.split("?")[1]);
const { data: workspace } = useGetWorkspaceById(localStorage.getItem("projectData.id") ?? "");
const { data: integrationAuth } = useGetIntegrationAuthById((integrationAuthId as string) ?? "");
const { data: integrationAuthApps } = useGetIntegrationAuthApps({
integrationAuthId: (integrationAuthId as string) ?? ""
});
const { integrationAuthId } = queryString.parse(router.asPath.split("?")[1]);
const { data: workspace } = useGetWorkspaceById(localStorage.getItem("projectData.id") ?? "");
const { data: integrationAuth } = useGetIntegrationAuthById((integrationAuthId as string) ?? "");
const { data: integrationAuthApps } = useGetIntegrationAuthApps({
integrationAuthId: (integrationAuthId as string) ?? ""
});
const [selectedSourceEnvironment, setSelectedSourceEnvironment] = useState("");
const [targetApp, setTargetApp] = useState("");
const [targetAppId, setTargetAppId] = useState("");
const [selectedSourceEnvironment, setSelectedSourceEnvironment] = useState("");
const [targetApp, setTargetApp] = useState("");
const [targetAppId, setTargetAppId] = useState("");
const [isLoading, setIsLoading] = useState(false);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
if (workspace) {
setSelectedSourceEnvironment(workspace.environments[0].slug);
}
}, [workspace]);
useEffect(() => {
if (integrationAuthApps) {
if (integrationAuthApps.length > 0) {
setTargetApp(integrationAuthApps[0].name);
setTargetAppId(String(integrationAuthApps[0].appId));
} else {
setTargetApp("none");
}
}
}, [integrationAuthApps]);
const handleButtonClick = async () => {
try {
if (!integrationAuth?.id) return;
setIsLoading(true);
await mutateAsync({
integrationAuthId: integrationAuth?.id,
isActive: true,
app: targetApp,
appId: targetAppId,
sourceEnvironment: selectedSourceEnvironment,
secretPath: "/",
});
setIsLoading(false);
router.push(`/integrations/${localStorage.getItem("projectData.id")}`);
} catch(err) {
console.error(err);
}
useEffect(() => {
if (workspace) {
setSelectedSourceEnvironment(workspace.environments[0].slug);
}
}, [workspace]);
return integrationAuth &&
workspace &&
selectedSourceEnvironment &&
integrationAuthApps &&
targetApp ? (
<div className="flex h-full w-full items-center justify-center bg-gradient-to-tr from-mineshaft-900 to-bunker-900">
<Card className="max-w-lg rounded-md p-0 border border-mineshaft-600">
<CardTitle className="text-left px-6" subTitle="Choose which environment in Infisical you want to sync with your Cloudflare Workers project.">Cloudflare Workers Integration</CardTitle>
<FormControl label="Infisical Project Environment" className="mt-2 px-6">
<Select
value={selectedSourceEnvironment}
onValueChange={(val) => setSelectedSourceEnvironment(val)}
className="w-full border border-mineshaft-500"
>
{workspace?.environments.map((sourceEnvironment) => (
<SelectItem
value={sourceEnvironment.slug}
key={`source-environment-${sourceEnvironment.slug}`}
>
{sourceEnvironment.name}
</SelectItem>
))}
</Select>
</FormControl>
<FormControl label="Cloudflare Workers Project" className="mt-4 px-6">
<Select
value={targetApp}
onValueChange={(val) => setTargetApp(val)}
className="w-full border border-mineshaft-500"
isDisabled={integrationAuthApps.length === 0}
>
{integrationAuthApps.length > 0 ? (
integrationAuthApps.map((integrationAuthApp) => (
<SelectItem
value={integrationAuthApp.name}
key={`target-app-${integrationAuthApp.name}`}
>
{integrationAuthApp.name}
</SelectItem>
))
) : (
<SelectItem value="none" key="target-app-none">
No apps found
</SelectItem>
)}
</Select>
</FormControl>
<Button
onClick={handleButtonClick}
color="mineshaft"
variant="outline_bg"
className="mt-2 mb-6 ml-auto mr-6"
isFullWidth={false}
isLoading={isLoading}
useEffect(() => {
if (integrationAuthApps) {
if (integrationAuthApps.length > 0) {
setTargetApp(integrationAuthApps[0].name);
setTargetAppId(String(integrationAuthApps[0].appId));
} else {
setTargetApp("none");
}
}
}, [integrationAuthApps]);
const handleButtonClick = async () => {
try {
if (!integrationAuth?._id) return;
setIsLoading(true);
await mutateAsync({
integrationAuthId: integrationAuth?._id,
isActive: true,
app: targetApp,
appId: targetAppId,
sourceEnvironment: selectedSourceEnvironment,
secretPath: "/"
});
setIsLoading(false);
router.push(`/integrations/${localStorage.getItem("projectData.id")}`);
} catch (err) {
console.error(err);
}
};
return integrationAuth &&
workspace &&
selectedSourceEnvironment &&
integrationAuthApps &&
targetApp ? (
<div className="flex h-full w-full items-center justify-center bg-gradient-to-tr from-mineshaft-900 to-bunker-900">
<Card className="max-w-lg rounded-md border border-mineshaft-600 p-0">
<CardTitle
className="px-6 text-left"
subTitle="Choose which environment in Infisical you want to sync with your Cloudflare Workers project."
>
Cloudflare Workers Integration
</CardTitle>
<FormControl label="Infisical Project Environment" className="mt-2 px-6">
<Select
value={selectedSourceEnvironment}
onValueChange={(val) => setSelectedSourceEnvironment(val)}
className="w-full border border-mineshaft-500"
>
{workspace?.environments.map((sourceEnvironment) => (
<SelectItem
value={sourceEnvironment.slug}
key={`source-environment-${sourceEnvironment.slug}`}
>
{sourceEnvironment.name}
</SelectItem>
))}
</Select>
</FormControl>
<FormControl label="Cloudflare Workers Project" className="mt-4 px-6">
<Select
value={targetApp}
onValueChange={(val) => setTargetApp(val)}
className="w-full border border-mineshaft-500"
isDisabled={integrationAuthApps.length === 0}
>
{integrationAuthApps.length > 0 ? (
integrationAuthApps.map((integrationAuthApp) => (
<SelectItem
value={integrationAuthApp.name}
key={`target-app-${integrationAuthApp.name}`}
>
Create Integration
</Button>
</Card>
</div>
) : (
<div />
);
{integrationAuthApp.name}
</SelectItem>
))
) : (
<SelectItem value="none" key="target-app-none">
No apps found
</SelectItem>
)}
</Select>
</FormControl>
<Button
onClick={handleButtonClick}
color="mineshaft"
variant="outline_bg"
className="mt-2 mb-6 ml-auto mr-6"
isFullWidth={false}
isLoading={isLoading}
>
Create Integration
</Button>
</Card>
</div>
) : (
<div />
);
}
CloudflareWorkersIntegrationPage.requireAuth = true;
CloudflareWorkersIntegrationPage.requireAuth = true;
@@ -1,9 +1,7 @@
import { useState } from "react";
import { useRouter } from "next/router";
import {
useSaveIntegrationAccessToken
} from "@app/hooks/api";
import { useSaveIntegrationAccessToken } from "@app/hooks/api";
import { Button, Card, CardTitle, FormControl, Input } from "../../../components/v2";
@@ -2,9 +2,7 @@ import { useEffect, useState } from "react";
import { useRouter } from "next/router";
import queryString from "query-string";
import {
useCreateIntegration
} from "@app/hooks/api";
import { useCreateIntegration } from "@app/hooks/api";
import {
Button,
@@ -64,7 +62,9 @@ export default function CodefreshCreateIntegrationPage() {
integrationAuthId: integrationAuth?.id,
isActive: true,
app: targetApp,
appId: integrationAuthApps?.find((integrationAuthApp) => integrationAuthApp.name === targetApp)?.appId,
appId: integrationAuthApps?.find(
(integrationAuthApp) => integrationAuthApp.name === targetApp
)?.appId,
sourceEnvironment: selectedSourceEnvironment,
secretPath
});
@@ -1,16 +1,14 @@
import { useState } from "react";
import { useRouter } from "next/router";
import {
useSaveIntegrationAccessToken
} from "@app/hooks/api";
import { useSaveIntegrationAccessToken } from "@app/hooks/api";
import { Button, Card, CardTitle, FormControl, Input } from "../../../components/v2";
export default function DigitalOceanAppPlatformCreateIntegrationPage() {
const router = useRouter();
const { mutateAsync } = useSaveIntegrationAccessToken();
const [apiKey, setApiKey] = useState("");
const [apiKeyErrorText, setApiKeyErrorText] = useState("");
const [isLoading, setIsLoading] = useState(false);
@@ -33,7 +31,9 @@ export default function DigitalOceanAppPlatformCreateIntegrationPage() {
setIsLoading(false);
router.push(`/integrations/digital-ocean-app-platform/create?integrationAuthId=${integrationAuth.id}`);
router.push(
`/integrations/digital-ocean-app-platform/create?integrationAuthId=${integrationAuth.id}`
);
} catch (err) {
console.error(err);
}
@@ -2,9 +2,7 @@ import { useEffect, useState } from "react";
import { useRouter } from "next/router";
import queryString from "query-string";
import {
useCreateIntegration
} from "@app/hooks/api";
import { useCreateIntegration } from "@app/hooks/api";
import {
Button,
@@ -64,7 +62,9 @@ export default function DigitalOceanAppPlatformCreateIntegrationPage() {
integrationAuthId: integrationAuth?.id,
isActive: true,
app: targetApp,
appId: integrationAuthApps?.find((integrationAuthApp) => integrationAuthApp.name === targetApp)?.appId,
appId: integrationAuthApps?.find(
(integrationAuthApp) => integrationAuthApp.name === targetApp
)?.appId,
sourceEnvironment: selectedSourceEnvironment,
secretPath
});
@@ -9,9 +9,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { yupResolver } from "@hookform/resolvers/yup";
import * as yup from "yup";
import {
useSaveIntegrationAccessToken
} from "@app/hooks/api";
import { useSaveIntegrationAccessToken } from "@app/hooks/api";
import { Button, Card, CardTitle, FormControl, Input } from "../../../components/v2";
@@ -24,10 +22,7 @@ type FormData = yup.InferType<typeof schema>;
export default function FlyioAuthorizeIntegrationPage() {
const router = useRouter();
const {
control,
handleSubmit
} = useForm<FormData>({
const { control, handleSubmit } = useForm<FormData>({
resolver: yupResolver(schema),
defaultValues: {
accessToken: ""
@@ -35,38 +30,36 @@ export default function FlyioAuthorizeIntegrationPage() {
});
const { mutateAsync } = useSaveIntegrationAccessToken();
const [isLoading, setIsLoading] = useState(false);
const onFormSubmit = async ({
accessToken
}: FormData) => {
const onFormSubmit = async ({ accessToken }: FormData) => {
try {
setIsLoading(true);
const integrationAuth = await mutateAsync({
workspaceId: localStorage.getItem("projectData.id"),
integration: "flyio",
accessToken
});
setIsLoading(false);
router.push(`/integrations/flyio/create?integrationAuthId=${integrationAuth.id}`);
} catch (err) {
setIsLoading(false);
console.error(err);
}
}
};
return (
<div className="flex h-full w-full items-center justify-center">
<Head>
<title>Authorize Fly.io Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
<Card className="max-w-lg rounded-md border border-mineshaft-600 mb-12">
<CardTitle
className="text-left px-6 text-xl"
<Card className="mb-12 max-w-lg rounded-md border border-mineshaft-600">
<CardTitle
className="px-6 text-left text-xl"
subTitle="After adding your access token, you will be prompted to set up an integration for a particular Infisical project and environment."
>
<div className="flex flex-row items-center">
@@ -81,19 +74,19 @@ export default function FlyioAuthorizeIntegrationPage() {
<span className="ml-2.5">Fly.io Integration </span>
<Link href="https://infisical.com/docs/integrations/cloud/flyio" passHref>
<a target="_blank" rel="noopener noreferrer">
<div className="ml-2 mb-1 rounded-md text-yellow text-sm inline-block bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] opacity-80 hover:opacity-100 cursor-default">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5"/>
Docs
<FontAwesomeIcon icon={faArrowUpRightFromSquare} className="ml-1.5 text-xxs mb-[0.07rem]"/>
<div className="ml-2 mb-1 inline-block cursor-default rounded-md bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] text-sm text-yellow opacity-80 hover:opacity-100">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
Docs
<FontAwesomeIcon
icon={faArrowUpRightFromSquare}
className="ml-1.5 mb-[0.07rem] text-xxs"
/>
</div>
</a>
</Link>
</div>
</CardTitle>
<form
onSubmit={handleSubmit(onFormSubmit)}
className="px-6 text-right pb-8"
>
<form onSubmit={handleSubmit(onFormSubmit)} className="px-6 pb-8 text-right">
<Controller
control={control}
name="accessToken"
@@ -103,10 +96,7 @@ export default function FlyioAuthorizeIntegrationPage() {
errorText={error?.message}
isError={Boolean(error)}
>
<Input
{...field}
placeholder=""
/>
<Input {...field} placeholder="" />
</FormControl>
)}
/>
@@ -3,13 +3,16 @@ import Head from "next/head";
import Image from "next/image";
import Link from "next/link";
import { useRouter } from "next/router";
import { faArrowUpRightFromSquare, faBookOpen, faBugs, faCircleInfo } from "@fortawesome/free-solid-svg-icons";
import {
faArrowUpRightFromSquare,
faBookOpen,
faBugs,
faCircleInfo
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import queryString from "query-string";
import {
useCreateIntegration
} from "@app/hooks/api";
import { useCreateIntegration } from "@app/hooks/api";
import {
Button,
@@ -28,16 +31,19 @@ import { useGetWorkspaceById } from "../../../hooks/api/workspace";
export default function FlyioCreateIntegrationPage() {
const router = useRouter();
const { mutateAsync } = useCreateIntegration();
const { integrationAuthId } = queryString.parse(router.asPath.split("?")[1]);
const { data: workspace } = useGetWorkspaceById(localStorage.getItem("projectData.id") ?? "");
const { data: integrationAuth, isLoading: isIntegrationAuthLoading } = useGetIntegrationAuthById((integrationAuthId as string) ?? "");
const { data: integrationAuthApps, isLoading: isIntegrationAuthAppsLoading } = useGetIntegrationAuthApps({
integrationAuthId: (integrationAuthId as string) ?? ""
});
const { data: integrationAuth, isLoading: isIntegrationAuthLoading } = useGetIntegrationAuthById(
(integrationAuthId as string) ?? ""
);
const { data: integrationAuthApps, isLoading: isIntegrationAuthAppsLoading } =
useGetIntegrationAuthApps({
integrationAuthId: (integrationAuthId as string) ?? ""
});
const [selectedSourceEnvironment, setSelectedSourceEnvironment] = useState("");
const [secretPath, setSecretPath] = useState("/");
@@ -90,14 +96,14 @@ export default function FlyioCreateIntegrationPage() {
selectedSourceEnvironment &&
integrationAuthApps &&
targetApp ? (
<div className="flex flex-col h-full w-full items-center justify-center">
<div className="flex h-full w-full flex-col items-center justify-center">
<Head>
<title>Set Up Fly.io Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
<Card className="max-w-lg rounded-md border border-mineshaft-600">
<CardTitle
className="text-left px-6 text-xl"
<CardTitle
className="px-6 text-left text-xl"
subTitle="Choose which environment or folder in Infisical you want to sync to Fly.io environment variables."
>
<div className="flex flex-row items-center">
@@ -112,10 +118,13 @@ export default function FlyioCreateIntegrationPage() {
<span className="ml-2.5">Fly.io Integration </span>
<Link href="https://infisical.com/docs/integrations/cloud/flyio" passHref>
<a target="_blank" rel="noopener noreferrer">
<div className="ml-2 mb-1 rounded-md text-yellow text-sm inline-block bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] opacity-80 hover:opacity-100 cursor-default">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5"/>
<div className="ml-2 mb-1 inline-block cursor-default rounded-md bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] text-sm text-yellow opacity-80 hover:opacity-100">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
Docs
<FontAwesomeIcon icon={faArrowUpRightFromSquare} className="ml-1.5 text-xxs mb-[0.07rem]"/>
<FontAwesomeIcon
icon={faArrowUpRightFromSquare}
className="ml-1.5 mb-[0.07rem] text-xxs"
/>
</div>
</a>
</Link>
@@ -178,31 +187,48 @@ export default function FlyioCreateIntegrationPage() {
Create Integration
</Button>
</Card>
<div className="border-t border-mineshaft-800 w-full max-w-md mt-6"/>
<div className="flex flex-col bg-mineshaft-800 border border-mineshaft-600 w-full p-4 max-w-lg mt-6 rounded-md">
<div className="flex flex-row items-center"><FontAwesomeIcon icon={faCircleInfo} className="text-mineshaft-200 text-xl"/> <span className="ml-3 text-md text-mineshaft-100">Pro Tips</span></div>
<span className="text-mineshaft-300 text-sm mt-4">After creating an integration, your secrets will start syncing immediately. This might cause an unexpected override of current secrets in Fly.io with secrets from Infisical.</span>
<div className="mt-6 w-full max-w-md border-t border-mineshaft-800" />
<div className="mt-6 flex w-full max-w-lg flex-col rounded-md border border-mineshaft-600 bg-mineshaft-800 p-4">
<div className="flex flex-row items-center">
<FontAwesomeIcon icon={faCircleInfo} className="text-xl text-mineshaft-200" />{" "}
<span className="text-md ml-3 text-mineshaft-100">Pro Tips</span>
</div>
<span className="mt-4 text-sm text-mineshaft-300">
After creating an integration, your secrets will start syncing immediately. This might
cause an unexpected override of current secrets in Fly.io with secrets from Infisical.
</span>
</div>
</div>
) : (
<div className="flex justify-center items-center w-full h-full">
<div className="flex h-full w-full items-center justify-center">
<Head>
<title>Set Up Fly.io Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
{isIntegrationAuthLoading || isIntegrationAuthAppsLoading ? <img src="/images/loading/loading.gif" height={70} width={120} alt="infisical loading indicator" /> : <div className="max-w-md h-max p-6 border border-mineshaft-600 rounded-md bg-mineshaft-800 text-mineshaft-200 flex flex-col text-center">
<FontAwesomeIcon icon={faBugs} className="text-6xl my-2 inlineli"/>
<p>
Something went wrong. Please contact <a
className="inline underline underline-offset-4 decoration-primary-500 opacity-80 hover:opacity-100 text-mineshaft-100 duration-200 cursor-pointer"
target="_blank"
rel="noopener noreferrer"
href="mailto:[email protected]"
>
support@infisical.com
</a> if the issue persists.
</p>
</div>}
{isIntegrationAuthLoading || isIntegrationAuthAppsLoading ? (
<img
src="/images/loading/loading.gif"
height={70}
width={120}
alt="infisical loading indicator"
/>
) : (
<div className="flex h-max max-w-md flex-col rounded-md border border-mineshaft-600 bg-mineshaft-800 p-6 text-center text-mineshaft-200">
<FontAwesomeIcon icon={faBugs} className="inlineli my-2 text-6xl" />
<p>
Something went wrong. Please contact{" "}
<a
className="inline cursor-pointer text-mineshaft-100 underline decoration-primary-500 underline-offset-4 opacity-80 duration-200 hover:opacity-100"
target="_blank"
rel="noopener noreferrer"
href="mailto:[email protected]"
>
support@infisical.com
</a>{" "}
if the issue persists.
</p>
</div>
)}
</div>
);
}
@@ -12,9 +12,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { yupResolver } from "@hookform/resolvers/yup";
import * as yup from "yup";
import {
useGetCloudIntegrations,
useSaveIntegrationAccessToken} from "@app/hooks/api";
import { useGetCloudIntegrations, useSaveIntegrationAccessToken } from "@app/hooks/api";
import { Button, Card, CardTitle, FormControl, TextArea } from "../../../components/v2";
@@ -27,61 +25,60 @@ type FormData = yup.InferType<typeof schema>;
export default function GCPSecretManagerAuthorizeIntegrationPage() {
const router = useRouter();
const {
control,
handleSubmit
} = useForm<FormData>({
const { control, handleSubmit } = useForm<FormData>({
resolver: yupResolver(schema)
});
const { data: cloudIntegrations } = useGetCloudIntegrations();
const { mutateAsync } = useSaveIntegrationAccessToken();
const [isLoading, setIsLoading] = useState(false);
const handleIntegrateWithOAuth = () => {
if (!cloudIntegrations) return;
const integrationOption = cloudIntegrations.find((integration) => integration.slug === "gcp-secret-manager");
const integrationOption = cloudIntegrations.find(
(integration) => integration.slug === "gcp-secret-manager"
);
if (!integrationOption) return;
const state = crypto.randomBytes(16).toString("hex");
localStorage.setItem("latestCSRFToken", state);
const link = `https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/cloud-platform&response_type=code&access_type=offline&state=${state}&redirect_uri=${window.location.origin}/integrations/gcp-secret-manager/oauth2/callback&clientid=${integrationOption.clientId}`;
window.location.assign(link);
}
const onFormSubmit = async ({
accessToken
}: FormData) => {
};
const onFormSubmit = async ({ accessToken }: FormData) => {
try {
setIsLoading(true);
const integrationAuth = await mutateAsync({
workspaceId: localStorage.getItem("projectData.id"),
integration: "gcp-secret-manager",
refreshToken: accessToken
});
setIsLoading(false);
router.push(`/integrations/gcp-secret-manager/create?integrationAuthId=${integrationAuth.id}`);
router.push(
`/integrations/gcp-secret-manager/create?integrationAuthId=${integrationAuth.id}`
);
} catch (err) {
console.error(err);
setIsLoading(false);
}
}
};
return (
<div className="flex h-full w-full items-center justify-center">
<Head>
<title>Authorize GCP Secret Manager Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
<Card className="max-w-lg rounded-md border border-mineshaft-600 mb-12">
<CardTitle
className="text-left px-6 text-xl"
<Card className="mb-12 max-w-lg rounded-md border border-mineshaft-600">
<CardTitle
className="px-6 text-left text-xl"
subTitle="Connect Infisical to GCP Secret Manager to sync secrets."
>
<div className="flex flex-row items-center">
@@ -96,10 +93,13 @@ export default function GCPSecretManagerAuthorizeIntegrationPage() {
<span className="ml-1.5">GCP Secret Manager Integration </span>
<Link href="https://infisical.com/docs/integrations/cloud/gcp-secret-manager" passHref>
<a target="_blank" rel="noopener noreferrer">
<div className="ml-2 mb-1 rounded-md text-yellow text-sm inline-block bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] opacity-80 hover:opacity-100 cursor-default">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5"/>
<div className="ml-2 mb-1 inline-block cursor-default rounded-md bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] text-sm text-yellow opacity-80 hover:opacity-100">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
Docs
<FontAwesomeIcon icon={faArrowUpRightFromSquare} className="ml-1.5 text-xxs mb-[0.07rem]"/>
<FontAwesomeIcon
icon={faArrowUpRightFromSquare}
className="ml-1.5 mb-[0.07rem] text-xxs"
/>
</div>
</a>
</Link>
@@ -107,24 +107,21 @@ export default function GCPSecretManagerAuthorizeIntegrationPage() {
</CardTitle>
<div className="px-6">
<Button
colorSchema="primary"
variant="outline_bg"
onClick={handleIntegrateWithOAuth}
leftIcon={<FontAwesomeIcon icon={faGoogle} className="mr-2" />}
className="h-11 w-full mx-0 mt-4"
>
Continue with OAuth
colorSchema="primary"
variant="outline_bg"
onClick={handleIntegrateWithOAuth}
leftIcon={<FontAwesomeIcon icon={faGoogle} className="mr-2" />}
className="mx-0 mt-4 h-11 w-full"
>
Continue with OAuth
</Button>
<div className='w-full flex flex-row items-center my-4 py-2'>
<div className='w-full border-t border-mineshaft-400/40' />
<span className="mx-2 text-mineshaft-400 text-xs">or</span>
<div className='w-full border-t border-mineshaft-400/40' />
<div className="my-4 flex w-full flex-row items-center py-2">
<div className="w-full border-t border-mineshaft-400/40" />
<span className="mx-2 text-xs text-mineshaft-400">or</span>
<div className="w-full border-t border-mineshaft-400/40" />
</div>
</div>
<form
onSubmit={handleSubmit(onFormSubmit)}
className="px-6 text-right pb-8"
>
<form onSubmit={handleSubmit(onFormSubmit)} className="px-6 pb-8 text-right">
<Controller
control={control}
name="accessToken"
@@ -134,7 +131,7 @@ export default function GCPSecretManagerAuthorizeIntegrationPage() {
errorText={error?.message}
isError={Boolean(error)}
>
<TextArea
<TextArea
{...field}
className="h-48 border border-mineshaft-600 bg-bunker-900/80"
/>
@@ -12,9 +12,7 @@ import queryString from "query-string";
import * as yup from "yup";
import { usePopUp } from "@app/hooks";
import {
useCreateIntegration
} from "@app/hooks/api";
import { useCreateIntegration } from "@app/hooks/api";
import {
Button,
@@ -30,7 +28,8 @@ import {
Tab,
TabList,
TabPanel,
Tabs} from "../../../components/v2";
Tabs
} from "../../../components/v2";
import {
useGetIntegrationAuthApps,
useGetIntegrationAuthById
@@ -60,13 +59,8 @@ export default function GCPSecretManagerCreateIntegrationPage() {
const { popUp, handlePopUpOpen, handlePopUpToggle, handlePopUpClose } = usePopUp([
"confirmIntegration"
] as const);
const {
control,
handleSubmit,
setValue,
watch
} = useForm<FormData>({
const { control, handleSubmit, setValue, watch } = useForm<FormData>({
resolver: yupResolver(schema),
defaultValues: {
secretPath: "/",
@@ -77,7 +71,7 @@ export default function GCPSecretManagerCreateIntegrationPage() {
labelValue: "infisical"
}
});
const shouldLabel = watch("shouldLabel");
const selectedSourceEnvironment = watch("selectedSourceEnvironment");
@@ -87,19 +81,20 @@ export default function GCPSecretManagerCreateIntegrationPage() {
const { data: workspace } = useGetWorkspaceById(localStorage.getItem("projectData.id") ?? "");
const { data: integrationAuth } = useGetIntegrationAuthById((integrationAuthId as string) ?? "");
const { data: integrationAuthApps, isLoading: isIntegrationAuthAppsLoading } = useGetIntegrationAuthApps({
integrationAuthId: (integrationAuthId as string) ?? ""
});
const { data: integrationAuthApps, isLoading: isIntegrationAuthAppsLoading } =
useGetIntegrationAuthApps({
integrationAuthId: (integrationAuthId as string) ?? ""
});
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
if (shouldLabel) {
setValue("labelName", "managed-by");
setValue("labelValue", "infisical");
return;
}
setValue("labelName", "");
setValue("labelValue", "");
}, [shouldLabel]);
@@ -119,7 +114,7 @@ export default function GCPSecretManagerCreateIntegrationPage() {
}
}
}, [integrationAuthApps]);
const onFormSubmit = async ({
selectedSourceEnvironment: sce,
secretPath,
@@ -134,56 +129,57 @@ export default function GCPSecretManagerCreateIntegrationPage() {
setIsLoading(true);
if (!integrationAuth?.id) return;
await mutateAsync({
integrationAuthId: integrationAuth?.id,
isActive: true,
app: integrationAuthApps?.find((integrationAuthApp) => integrationAuthApp.appId === targetAppId)?.name,
app: integrationAuthApps?.find(
(integrationAuthApp) => integrationAuthApp.appId === targetAppId
)?.name,
appId: targetAppId,
sourceEnvironment: sce,
secretPath,
metadata: {
...(secretPrefix ? { secretPrefix } : {}),
...(secretSuffix ? { secretSuffix } : {}),
...(sl ? {
secretGCPLabel: {
labelName,
labelValue
}
} : {})
...(sl
? {
secretGCPLabel: {
labelName,
labelValue
}
}
: {})
}
});
setIsLoading(false);
router.push(`/integrations/${localStorage.getItem("projectData.id")}`);
} catch (err) {
console.error(err);
setIsLoading(false);
}
}
return integrationAuth &&
workspace &&
selectedSourceEnvironment &&
integrationAuthApps ? (
<form
};
return integrationAuth && workspace && selectedSourceEnvironment && integrationAuthApps ? (
<form
onSubmit={handleSubmit((data: FormData) => {
if (!data.secretPrefix && !data.secretSuffix && !data.shouldLabel) {
handlePopUpOpen("confirmIntegration", data);
handlePopUpOpen("confirmIntegration", data);
return;
}
onFormSubmit(data);
})}
className="flex flex-col h-full w-full items-center justify-center"
className="flex h-full w-full flex-col items-center justify-center"
>
<Card className="max-w-lg rounded-md border border-mineshaft-600">
<Head>
<title>Set Up GCP Secret Manager Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
<CardTitle
className="text-left px-6 text-xl mb-2"
<CardTitle
className="mb-2 px-6 text-left text-xl"
subTitle="Select which environment or folder in Infisical you want to sync to GCP Secret Manager."
>
<div className="flex flex-row items-center">
@@ -198,10 +194,13 @@ export default function GCPSecretManagerCreateIntegrationPage() {
<span className="ml-1.5">GCP Secret Manager Integration </span>
<Link href="https://infisical.com/docs/integrations/cloud/gcp-secret-manager" passHref>
<a target="_blank" rel="noopener noreferrer">
<div className="ml-2 mb-1 rounded-md text-yellow text-sm inline-block bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] opacity-80 hover:opacity-100 cursor-default">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5"/>
<div className="ml-2 mb-1 inline-block cursor-default rounded-md bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] text-sm text-yellow opacity-80 hover:opacity-100">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
Docs
<FontAwesomeIcon icon={faArrowUpRightFromSquare} className="ml-1.5 text-xxs mb-[0.07rem]"/>
<FontAwesomeIcon
icon={faArrowUpRightFromSquare}
className="ml-1.5 mb-[0.07rem] text-xxs"
/>
</div>
</a>
</Link>
@@ -209,7 +208,7 @@ export default function GCPSecretManagerCreateIntegrationPage() {
</CardTitle>
<Tabs defaultValue={TabSections.Connection} className="px-6">
<TabList>
<div className="flex flex-row border-b border-mineshaft-600 w-full">
<div className="flex w-full flex-row border-b border-mineshaft-600">
<Tab value={TabSections.Connection}>Connection</Tab>
<Tab value={TabSections.Options}>Options</Tab>
</div>
@@ -250,26 +249,23 @@ export default function GCPSecretManagerCreateIntegrationPage() {
)}
/>
<Controller
control={control}
defaultValue=""
name="secretPath"
render={({ field, fieldState: { error } }) => (
<FormControl
label="Secrets Path"
isError={Boolean(error)}
errorText={error?.message}
>
<Input
{...field}
placeholder="/"
/>
</FormControl>
)}
control={control}
defaultValue=""
name="secretPath"
render={({ field, fieldState: { error } }) => (
<FormControl
label="Secrets Path"
isError={Boolean(error)}
errorText={error?.message}
>
<Input {...field} placeholder="/" />
</FormControl>
)}
/>
<Controller
control={control}
name="targetAppId"
render={({ field: { onChange, ...field }, fieldState: { error } }) => {
control={control}
name="targetAppId"
render={({ field: { onChange, ...field }, fieldState: { error } }) => {
return (
<FormControl
label="GCP Project"
@@ -280,7 +276,7 @@ export default function GCPSecretManagerCreateIntegrationPage() {
{...field}
onValueChange={(e) => {
if (e === "") return;
onChange(e)
onChange(e);
}}
className="w-full"
>
@@ -300,7 +296,7 @@ export default function GCPSecretManagerCreateIntegrationPage() {
)}
</Select>
</FormControl>
)
);
}}
/>
</motion.div>
@@ -317,32 +313,26 @@ export default function GCPSecretManagerCreateIntegrationPage() {
control={control}
name="secretPrefix"
render={({ field, fieldState: { error } }) => (
<FormControl
label="Secret Prefix"
isError={Boolean(error)}
errorText={error?.message}
>
<Input
{...field}
placeholder="INFISICAL_"
/>
</FormControl>
<FormControl
label="Secret Prefix"
isError={Boolean(error)}
errorText={error?.message}
>
<Input {...field} placeholder="INFISICAL_" />
</FormControl>
)}
/>
<Controller
control={control}
name="secretSuffix"
render={({ field, fieldState: { error } }) => (
<FormControl
label="Secret Suffix"
isError={Boolean(error)}
errorText={error?.message}
>
<Input
{...field}
placeholder="_INFISICAL"
/>
</FormControl>
<FormControl
label="Secret Suffix"
isError={Boolean(error)}
errorText={error?.message}
>
<Input {...field} placeholder="_INFISICAL" />
</FormControl>
)}
/>
<div className="mt-8 mb-[2.36rem]">
@@ -366,32 +356,26 @@ export default function GCPSecretManagerCreateIntegrationPage() {
control={control}
name="labelName"
render={({ field, fieldState: { error } }) => (
<FormControl
label="Label Name"
isError={Boolean(error)}
errorText={error?.message}
>
<Input
{...field}
placeholder="managed-by"
/>
</FormControl>
<FormControl
label="Label Name"
isError={Boolean(error)}
errorText={error?.message}
>
<Input {...field} placeholder="managed-by" />
</FormControl>
)}
/>
<Controller
control={control}
name="labelValue"
render={({ field, fieldState: { error } }) => (
<FormControl
label="Label Name"
isError={Boolean(error)}
errorText={error?.message}
>
<Input
{...field}
placeholder="infisical"
/>
</FormControl>
<FormControl
label="Label Name"
isError={Boolean(error)}
errorText={error?.message}
>
<Input {...field} placeholder="infisical" />
</FormControl>
)}
/>
</div>
@@ -424,56 +408,66 @@ export default function GCPSecretManagerCreateIntegrationPage() {
</span>
</div> */}
<Modal
isOpen={popUp.confirmIntegration?.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle("confirmIntegration", isOpen)}
isOpen={popUp.confirmIntegration?.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle("confirmIntegration", isOpen)}
>
<ModalContent
title="Heads Up"
footerContent={
<div className="flex items-center space-x-2">
<Button onClick={() => onFormSubmit(popUp.confirmIntegration?.data as FormData)}>
Continue Anyway
</Button>
<Button
onClick={() => handlePopUpClose("confirmIntegration")}
variant="outline_bg"
colorSchema="secondary"
>
Cancel
</Button>
</div>
}
>
<ModalContent
title="Heads Up"
footerContent={
<div className="flex items-center space-x-2">
<Button onClick={() => onFormSubmit(popUp.confirmIntegration?.data as FormData)}>
Continue Anyway
</Button>
<Button
onClick={() => handlePopUpClose("confirmIntegration")}
variant="outline_bg"
colorSchema="secondary"
>
Cancel
</Button>
</div>
}
>
<p>
You&apos;re about to overwrite any existing secrets in GCP Secret Manager.
</p>
<p className="mt-4">
To avoid this behavior, you may consider adding a secret prefix/suffix or enabling labeling in the options tab.
</p>
</ModalContent>
</Modal>
<p>You&apos;re about to overwrite any existing secrets in GCP Secret Manager.</p>
<p className="mt-4">
To avoid this behavior, you may consider adding a secret prefix/suffix or enabling
labeling in the options tab.
</p>
</ModalContent>
</Modal>
</form>
) : (
<div className="flex justify-center items-center w-full h-full">
<div className="flex h-full w-full items-center justify-center">
<Head>
<title>Set Up GCP Secret Manager Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
{isIntegrationAuthAppsLoading ? <img src="/images/loading/loading.gif" height={70} width={120} alt="infisical loading indicator" /> : <div className="max-w-md h-max p-6 border border-mineshaft-600 rounded-md bg-mineshaft-800 text-mineshaft-200 flex flex-col text-center">
<FontAwesomeIcon icon={faBugs} className="text-6xl my-2 inlineli"/>
<p>
Something went wrong. Please contact <a
className="inline underline underline-offset-4 decoration-primary-500 opacity-80 hover:opacity-100 text-mineshaft-100 duration-200 cursor-pointer"
target="_blank"
rel="noopener noreferrer"
href="mailto:[email protected]"
>
support@infisical.com
</a> if the issue persists.
</p>
</div>}
{isIntegrationAuthAppsLoading ? (
<img
src="/images/loading/loading.gif"
height={70}
width={120}
alt="infisical loading indicator"
/>
) : (
<div className="flex h-max max-w-md flex-col rounded-md border border-mineshaft-600 bg-mineshaft-800 p-6 text-center text-mineshaft-200">
<FontAwesomeIcon icon={faBugs} className="inlineli my-2 text-6xl" />
<p>
Something went wrong. Please contact{" "}
<a
className="inline cursor-pointer text-mineshaft-100 underline decoration-primary-500 underline-offset-4 opacity-80 duration-200 hover:opacity-100"
target="_blank"
rel="noopener noreferrer"
href="mailto:[email protected]"
>
support@infisical.com
</a>{" "}
if the issue persists.
</p>
</div>
)}
</div>
);
}
GCPSecretManagerCreateIntegrationPage.requireAuth = true;
GCPSecretManagerCreateIntegrationPage.requireAuth = true;
@@ -2,15 +2,13 @@ import { useEffect } from "react";
import { useRouter } from "next/router";
import queryString from "query-string";
import {
useAuthorizeIntegration
} from "@app/hooks/api";
import { useAuthorizeIntegration } from "@app/hooks/api";
export default function GCPSecretManagerOAuth2CallbackPage() {
const router = useRouter();
const { mutateAsync } = useAuthorizeIntegration();
const router = useRouter();
const { mutateAsync } = useAuthorizeIntegration();
const { code, state } = queryString.parse(router.asPath.split("?")[1]);
const { code, state } = queryString.parse(router.asPath.split("?")[1]);
useEffect(() => {
(async () => {
@@ -24,8 +22,10 @@ export default function GCPSecretManagerOAuth2CallbackPage() {
code: code as string,
integration: "gcp-secret-manager"
});
router.push(`/integrations/gcp-secret-manager/create?integrationAuthId=${integrationAuth.id}`);
router.push(
`/integrations/gcp-secret-manager/create?integrationAuthId=${integrationAuth.id}`
);
} catch (err) {
console.error(err);
}
+107 -52
View File
@@ -3,14 +3,19 @@ import Head from "next/head";
import Image from "next/image";
import Link from "next/link";
import { useRouter } from "next/router";
import { faAngleDown, faArrowUpRightFromSquare, faBookOpen, faBugs, faCheckCircle, faCircleInfo } from "@fortawesome/free-solid-svg-icons";
import {
faAngleDown,
faArrowUpRightFromSquare,
faBookOpen,
faBugs,
faCheckCircle,
faCircleInfo
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { motion } from "framer-motion";
import queryString from "query-string";
import {
useCreateIntegration
} from "@app/hooks/api";
import { useCreateIntegration } from "@app/hooks/api";
import {
Button,
@@ -48,9 +53,10 @@ export default function GitHubCreateIntegrationPage() {
const { data: workspace } = useGetWorkspaceById(localStorage.getItem("projectData.id") ?? "");
const { data: integrationAuth } = useGetIntegrationAuthById((integrationAuthId as string) ?? "");
const { data: integrationAuthApps, isLoading: isIntegrationAuthAppsLoading } = useGetIntegrationAuthApps({
integrationAuthId: (integrationAuthId as string) ?? ""
});
const { data: integrationAuthApps, isLoading: isIntegrationAuthAppsLoading } =
useGetIntegrationAuthApps({
integrationAuthId: (integrationAuthId as string) ?? ""
});
const [selectedSourceEnvironment, setSelectedSourceEnvironment] = useState("");
const [secretPath, setSecretPath] = useState("/");
@@ -81,8 +87,8 @@ export default function GitHubCreateIntegrationPage() {
if (!integrationAuth?.id) return;
const targetApps = integrationAuthApps?.filter(
(integrationAuthApp) => targetAppIds.includes(String(integrationAuthApp.appId))
const targetApps = integrationAuthApps?.filter((integrationAuthApp) =>
targetAppIds.includes(String(integrationAuthApp.appId))
);
if (!targetApps) return;
@@ -99,7 +105,7 @@ export default function GitHubCreateIntegrationPage() {
metadata: {
secretSuffix
}
})
});
})
);
@@ -115,18 +121,18 @@ export default function GitHubCreateIntegrationPage() {
selectedSourceEnvironment &&
integrationAuthApps &&
targetAppIds ? (
<div className="flex flex-col h-full w-full items-center justify-center">
<div className="flex h-full w-full flex-col items-center justify-center">
<Head>
<title>Set Up GitHub Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
<Card className="max-w-lg rounded-md border border-mineshaft-600 p-0">
<CardTitle
className="text-left px-6 text-xl"
<CardTitle
className="px-6 text-left text-xl"
subTitle="Choose which environment in Infisical you want to sync to environment variables in GitHub."
>
<div className="flex flex-row items-center">
<div className="inline flex items-center bg-mineshaft-200 rounded-full">
<div className="inline flex items-center rounded-full bg-mineshaft-200">
<Image
src="/images/integrations/GitHub.png"
height={30}
@@ -137,10 +143,13 @@ export default function GitHubCreateIntegrationPage() {
<span className="ml-2.5">GitHub Integration </span>
<Link href="https://infisical.com/docs/integrations/cicd/githubactions" passHref>
<a target="_blank" rel="noopener noreferrer">
<div className="ml-2 mb-1 rounded-md text-yellow text-sm inline-block bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] opacity-80 hover:opacity-100 cursor-default">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5"/>
<div className="ml-2 mb-1 inline-block cursor-default rounded-md bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] text-sm text-yellow opacity-80 hover:opacity-100">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
Docs
<FontAwesomeIcon icon={faArrowUpRightFromSquare} className="ml-1.5 text-xxs mb-[0.07rem]"/>
<FontAwesomeIcon
icon={faArrowUpRightFromSquare}
className="ml-1.5 mb-[0.07rem] text-xxs"
/>
</div>
</a>
</Link>
@@ -148,7 +157,7 @@ export default function GitHubCreateIntegrationPage() {
</CardTitle>
<Tabs defaultValue={TabSections.Connection} className="px-6">
<TabList>
<div className="flex flex-row border-b border-mineshaft-600 w-full">
<div className="flex w-full flex-row border-b border-mineshaft-600">
<Tab value={TabSections.Connection}>Connection</Tab>
<Tab value={TabSections.Options}>Options</Tab>
</div>
@@ -187,17 +196,27 @@ export default function GitHubCreateIntegrationPage() {
<FormControl label="GitHub Repo">
<DropdownMenu>
<DropdownMenuTrigger asChild>
{(integrationAuthApps.length > 0) ? <div className="w-full cursor-pointer border border-mineshaft-600 inline-flex items-center justify-between rounded-md bg-mineshaft-900 px-3 py-2 font-inter text-sm font-normal text-bunker-200 outline-none data-[placeholder]:text-mineshaft-200">
{targetAppIds.length === 1 ? integrationAuthApps?.find(
(integrationAuthApp) => targetAppIds[0] === String(integrationAuthApp.appId)
)?.name : `${targetAppIds.length} repositories selected`}
{integrationAuthApps.length > 0 ? (
<div className="inline-flex w-full cursor-pointer items-center justify-between rounded-md border border-mineshaft-600 bg-mineshaft-900 px-3 py-2 font-inter text-sm font-normal text-bunker-200 outline-none data-[placeholder]:text-mineshaft-200">
{targetAppIds.length === 1
? integrationAuthApps?.find(
(integrationAuthApp) =>
targetAppIds[0] === String(integrationAuthApp.appId)
)?.name
: `${targetAppIds.length} repositories selected`}
<FontAwesomeIcon icon={faAngleDown} className="text-xs" />
</div> : <div className="w-full cursor-default border border-mineshaft-600 inline-flex items-center justify-between rounded-md bg-mineshaft-900 px-3 py-2 font-inter text-sm font-normal text-bunker-200 outline-none data-[placeholder]:text-mineshaft-200">
</div>
) : (
<div className="inline-flex w-full cursor-default items-center justify-between rounded-md border border-mineshaft-600 bg-mineshaft-900 px-3 py-2 font-inter text-sm font-normal text-bunker-200 outline-none data-[placeholder]:text-mineshaft-200">
No repositories found
</div>}
</div>
)}
</DropdownMenuTrigger>
<DropdownMenuContent align="start" className="z-[100] max-h-80 overflow-y-scroll thin-scrollbar">
{(integrationAuthApps.length > 0) ? (
<DropdownMenuContent
align="start"
className="thin-scrollbar z-[100] max-h-80 overflow-y-scroll"
>
{integrationAuthApps.length > 0 ? (
integrationAuthApps.map((integrationAuthApp) => {
const isSelected = targetAppIds.includes(String(integrationAuthApp.appId));
@@ -205,20 +224,39 @@ export default function GitHubCreateIntegrationPage() {
<DropdownMenuItem
onClick={() => {
if (targetAppIds.includes(String(integrationAuthApp.appId))) {
setTargetAppIds(targetAppIds.filter((appId) => appId !== String(integrationAuthApp.appId)));
setTargetAppIds(
targetAppIds.filter(
(appId) => appId !== String(integrationAuthApp.appId)
)
);
} else {
setTargetAppIds([...targetAppIds, String(integrationAuthApp.appId)]);
setTargetAppIds([
...targetAppIds,
String(integrationAuthApp.appId)
]);
}
}}
key={integrationAuthApp.appId}
icon={isSelected ? <FontAwesomeIcon icon={faCheckCircle} className="text-primary pr-0.5" /> : <div className="pl-[1.01rem]"/>}
icon={
isSelected ? (
<FontAwesomeIcon
icon={faCheckCircle}
className="pr-0.5 text-primary"
/>
) : (
<div className="pl-[1.01rem]" />
)
}
iconPos="left"
className="w-[28.4rem] text-sm"
>
{integrationAuthApp.name}
</DropdownMenuItem>
)})
) : <div/>}
</DropdownMenuItem>
);
})
) : (
<div />
)}
</DropdownMenuContent>
</DropdownMenu>
</FormControl>
@@ -253,31 +291,48 @@ export default function GitHubCreateIntegrationPage() {
Create Integration
</Button>
</Card>
<div className="border-t border-mineshaft-800 w-full max-w-md mt-6"/>
<div className="flex flex-col bg-mineshaft-800 border border-mineshaft-600 w-full p-4 max-w-lg mt-6 rounded-md">
<div className="flex flex-row items-center"><FontAwesomeIcon icon={faCircleInfo} className="text-mineshaft-200 text-xl"/> <span className="ml-3 text-md text-mineshaft-100">Pro Tips</span></div>
<span className="text-mineshaft-300 text-sm mt-4">After creating an integration, your secrets will start syncing immediately. This might cause an unexpected override of current secrets in GitHub with secrets from Infisical.</span>
<div className="mt-6 w-full max-w-md border-t border-mineshaft-800" />
<div className="mt-6 flex w-full max-w-lg flex-col rounded-md border border-mineshaft-600 bg-mineshaft-800 p-4">
<div className="flex flex-row items-center">
<FontAwesomeIcon icon={faCircleInfo} className="text-xl text-mineshaft-200" />{" "}
<span className="text-md ml-3 text-mineshaft-100">Pro Tips</span>
</div>
<span className="mt-4 text-sm text-mineshaft-300">
After creating an integration, your secrets will start syncing immediately. This might
cause an unexpected override of current secrets in GitHub with secrets from Infisical.
</span>
</div>
</div>
) : (
<div className="flex justify-center items-center w-full h-full">
<div className="flex h-full w-full items-center justify-center">
<Head>
<title>Set Up GitHub Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
{isIntegrationAuthAppsLoading ? <img src="/images/loading/loading.gif" height={70} width={120} alt="infisical loading indicator" /> : <div className="max-w-md h-max p-6 border border-mineshaft-600 rounded-md bg-mineshaft-800 text-mineshaft-200 flex flex-col text-center">
<FontAwesomeIcon icon={faBugs} className="text-6xl my-2 inlineli"/>
<p>
Something went wrong. Please contact <a
className="inline underline underline-offset-4 decoration-primary-500 opacity-80 hover:opacity-100 text-mineshaft-100 duration-200 cursor-pointer"
target="_blank"
rel="noopener noreferrer"
href="mailto:[email protected]"
>
support@infisical.com
</a> if the issue persists.
</p>
</div>}
{isIntegrationAuthAppsLoading ? (
<img
src="/images/loading/loading.gif"
height={70}
width={120}
alt="infisical loading indicator"
/>
) : (
<div className="flex h-max max-w-md flex-col rounded-md border border-mineshaft-600 bg-mineshaft-800 p-6 text-center text-mineshaft-200">
<FontAwesomeIcon icon={faBugs} className="inlineli my-2 text-6xl" />
<p>
Something went wrong. Please contact{" "}
<a
className="inline cursor-pointer text-mineshaft-100 underline decoration-primary-500 underline-offset-4 opacity-80 duration-200 hover:opacity-100"
target="_blank"
rel="noopener noreferrer"
href="mailto:[email protected]"
>
support@infisical.com
</a>{" "}
if the issue persists.
</p>
</div>
)}
</div>
);
}
@@ -2,9 +2,7 @@ import { useEffect } from "react";
import { useRouter } from "next/router";
import queryString from "query-string";
import {
useAuthorizeIntegration
} from "@app/hooks/api";
import { useAuthorizeIntegration } from "@app/hooks/api";
export default function GitHubOAuth2CallbackPage() {
const router = useRouter();
@@ -20,10 +20,7 @@ const schema = yup.object({
type FormData = yup.InferType<typeof schema>;
export default function GitLabAuthorizeIntegrationPage() {
const {
control,
handleSubmit
} = useForm<FormData>({
const { control, handleSubmit } = useForm<FormData>({
resolver: yupResolver(schema),
defaultValues: {
gitLabURL: ""
@@ -31,35 +28,38 @@ export default function GitLabAuthorizeIntegrationPage() {
});
const { data: cloudIntegrations } = useGetCloudIntegrations();
const onFormSubmit = ({
gitLabURL
}: FormData) => {
const onFormSubmit = ({ gitLabURL }: FormData) => {
if (!cloudIntegrations) return;
const integrationOption = cloudIntegrations.find((integration) => integration.slug === "gitlab");
const integrationOption = cloudIntegrations.find(
(integration) => integration.slug === "gitlab"
);
if (!integrationOption) return;
const baseURL = (gitLabURL as string).trim() === "" ? "https://gitlab.com" : (gitLabURL as string).trim();
const baseURL =
(gitLabURL as string).trim() === "" ? "https://gitlab.com" : (gitLabURL as string).trim();
const csrfToken = crypto.randomBytes(16).toString("hex");
localStorage.setItem("latestCSRFToken", csrfToken);
const state = `${csrfToken}|${(gitLabURL as string).trim() === "" ? "" : (gitLabURL as string).trim()}`;
const state = `${csrfToken}|${
(gitLabURL as string).trim() === "" ? "" : (gitLabURL as string).trim()
}`;
const link = `${baseURL}/oauth/authorize?clientid=${integrationOption.clientId}&redirect_uri=${window.location.origin}/integrations/gitlab/oauth2/callback&response_type=code&state=${state}`;
window.location.assign(link);
}
};
return (
<div className="flex h-full w-full items-center justify-center">
<Head>
<title>Authorize GitLab Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
<Card className="max-w-lg rounded-md border border-mineshaft-600 mb-12">
<CardTitle
className="text-left px-6 text-xl"
<Card className="mb-12 max-w-lg rounded-md border border-mineshaft-600">
<CardTitle
className="px-6 text-left text-xl"
subTitle="Authorize this integration to sync secrets from Infisical to GitLab. If no self-hosted GitLab URL is specified, then Infisical will connect you to GitLab Cloud."
>
<div className="flex flex-row items-center">
@@ -74,19 +74,19 @@ export default function GitLabAuthorizeIntegrationPage() {
<span className="ml-2.5">GitLab Integration </span>
<Link href="https://infisical.com/docs/integrations/cicd/gitlab" passHref>
<a target="_blank" rel="noopener noreferrer">
<div className="ml-2 mb-1 rounded-md text-yellow text-sm inline-block bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] opacity-80 hover:opacity-100 cursor-default">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5"/>
<div className="ml-2 mb-1 inline-block cursor-default rounded-md bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] text-sm text-yellow opacity-80 hover:opacity-100">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
Docs
<FontAwesomeIcon icon={faArrowUpRightFromSquare} className="ml-1.5 text-xxs mb-[0.07rem]"/>
<FontAwesomeIcon
icon={faArrowUpRightFromSquare}
className="ml-1.5 mb-[0.07rem] text-xxs"
/>
</div>
</a>
</Link>
</div>
</CardTitle>
<form
onSubmit={handleSubmit(onFormSubmit)}
className="px-6 text-right pb-8"
>
<form onSubmit={handleSubmit(onFormSubmit)} className="px-6 pb-8 text-right">
<Controller
control={control}
name="gitLabURL"
@@ -96,10 +96,7 @@ export default function GitLabAuthorizeIntegrationPage() {
errorText={error?.message}
isError={Boolean(error)}
>
<Input
{...field}
placeholder="https://self-hosted-gitlab.com"
/>
<Input {...field} placeholder="https://self-hosted-gitlab.com" />
</FormControl>
)}
/>
+140 -150
View File
@@ -12,9 +12,7 @@ import queryString from "query-string";
import * as yup from "yup";
import { usePopUp } from "@app/hooks";
import {
useCreateIntegration
} from "@app/hooks/api";
import { useCreateIntegration } from "@app/hooks/api";
import {
Button,
@@ -49,7 +47,10 @@ enum TabSections {
}
const schema = yup.object({
targetEntity: yup.string().oneOf(gitLabEntities.map(entity => entity.value), "Invalid entity type"),
targetEntity: yup.string().oneOf(
gitLabEntities.map((entity) => entity.value),
"Invalid entity type"
),
targetTeamId: yup.string(),
selectedSourceEnvironment: yup.string().required("Source environment is required"),
secretPath: yup.string().required("Secret path is required"),
@@ -66,20 +67,15 @@ export default function GitLabCreateIntegrationPage() {
const { popUp, handlePopUpOpen, handlePopUpToggle, handlePopUpClose } = usePopUp([
"confirmIntegration"
] as const);
const {
control,
handleSubmit,
setValue,
watch
} = useForm<FormData>({
resolver: yupResolver(schema),
defaultValues: {
targetEntity: "individual",
secretPath: "/",
secretPrefix: "",
secretSuffix: ""
}
const { control, handleSubmit, setValue, watch } = useForm<FormData>({
resolver: yupResolver(schema),
defaultValues: {
targetEntity: "individual",
secretPath: "/",
secretPrefix: "",
secretSuffix: ""
}
});
const selectedSourceEnvironment = watch("selectedSourceEnvironment");
const targetEntity = watch("targetEntity");
@@ -93,17 +89,16 @@ export default function GitLabCreateIntegrationPage() {
const { data: workspace } = useGetWorkspaceById(localStorage.getItem("projectData.id") ?? "");
const { data: integrationAuth } = useGetIntegrationAuthById((integrationAuthId as string) ?? "");
const { data: integrationAuthApps, isLoading: isIntegrationAuthAppsLoading } = useGetIntegrationAuthApps({
integrationAuthId: (integrationAuthId as string) ?? "",
...(targetTeamId ? { teamId: targetTeamId } : {})
});
const { data: integrationAuthTeams, isLoading: isintegrationAuthTeamsLoading } = useGetIntegrationAuthTeams(
(integrationAuthId as string) ?? ""
);
const { data: integrationAuthApps, isLoading: isIntegrationAuthAppsLoading } =
useGetIntegrationAuthApps({
integrationAuthId: (integrationAuthId as string) ?? "",
...(targetTeamId ? { teamId: targetTeamId } : {})
});
const { data: integrationAuthTeams, isLoading: isintegrationAuthTeamsLoading } =
useGetIntegrationAuthTeams((integrationAuthId as string) ?? "");
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
if (workspace) {
setValue("selectedSourceEnvironment", workspace.environments[0].slug);
@@ -147,11 +142,13 @@ export default function GitLabCreateIntegrationPage() {
try {
setIsLoading(true);
if (!integrationAuth?.id) return;
await mutateAsync({
integrationAuthId: integrationAuth?.id,
isActive: true,
app: integrationAuthApps?.find((integrationAuthApp) => String(integrationAuthApp.appId) === targetAppId)?.name,
app: integrationAuthApps?.find(
(integrationAuthApp) => String(integrationAuthApp.appId) === targetAppId
)?.name,
appId: String(targetAppId),
sourceEnvironment: sse,
targetEnvironment: targetEnvironment === "" ? "*" : targetEnvironment,
@@ -168,31 +165,31 @@ export default function GitLabCreateIntegrationPage() {
console.error(err);
setIsLoading(false);
}
}
};
return integrationAuth &&
workspace &&
selectedSourceEnvironment &&
integrationAuthApps &&
integrationAuthTeams ? (
<form
<form
onSubmit={handleSubmit((data: FormData) => {
if (!data.secretPrefix && !data.secretSuffix) {
handlePopUpOpen("confirmIntegration", data);
handlePopUpOpen("confirmIntegration", data);
return;
}
onFormSubmit(data);
})}
className="flex flex-col h-full w-full items-center justify-center"
className="flex h-full w-full flex-col items-center justify-center"
>
<Head>
<title>Set Up GitLab Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
<Card className="max-w-lg rounded-md border border-mineshaft-600">
<CardTitle
className="text-left px-6 text-xl"
<CardTitle
className="px-6 text-left text-xl"
subTitle="Select which environment or folder in Infisical you want to sync to GitLab's environment variables."
>
<div className="flex flex-row items-center">
@@ -207,10 +204,13 @@ export default function GitLabCreateIntegrationPage() {
<span className="ml-2.5">GitLab Integration </span>
<Link href="https://infisical.com/docs/integrations/cicd/gitlab" passHref>
<a target="_blank" rel="noopener noreferrer">
<div className="ml-2 mb-1 rounded-md text-yellow text-sm inline-block bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] opacity-80 hover:opacity-100 cursor-default">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5"/>
<div className="ml-2 mb-1 inline-block cursor-default rounded-md bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] text-sm text-yellow opacity-80 hover:opacity-100">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
Docs
<FontAwesomeIcon icon={faArrowUpRightFromSquare} className="ml-1.5 text-xxs mb-[0.07rem]"/>
<FontAwesomeIcon
icon={faArrowUpRightFromSquare}
className="ml-1.5 mb-[0.07rem] text-xxs"
/>
</div>
</a>
</Link>
@@ -218,7 +218,7 @@ export default function GitLabCreateIntegrationPage() {
</CardTitle>
<Tabs defaultValue={TabSections.Connection} className="px-6">
<TabList>
<div className="flex flex-row border-b border-mineshaft-600 w-full">
<div className="flex w-full flex-row border-b border-mineshaft-600">
<Tab value={TabSections.Connection}>Connection</Tab>
<Tab value={TabSections.Options}>Options</Tab>
</div>
@@ -259,21 +259,18 @@ export default function GitLabCreateIntegrationPage() {
)}
/>
<Controller
control={control}
defaultValue=""
name="secretPath"
render={({ field, fieldState: { error } }) => (
<FormControl
label="Secrets Path"
isError={Boolean(error)}
errorText={error?.message}
>
<Input
{...field}
placeholder="/"
/>
</FormControl>
)}
control={control}
defaultValue=""
name="secretPath"
render={({ field, fieldState: { error } }) => (
<FormControl
label="Secrets Path"
isError={Boolean(error)}
errorText={error?.message}
>
<Input {...field} placeholder="/" />
</FormControl>
)}
/>
<Controller
control={control}
@@ -284,11 +281,7 @@ export default function GitLabCreateIntegrationPage() {
errorText={error?.message}
isError={Boolean(error)}
>
<Select
{...field}
onValueChange={(e) => onChange(e)}
className="w-full"
>
<Select {...field} onValueChange={(e) => onChange(e)} className="w-full">
{gitLabEntities.map((entity) => {
return (
<SelectItem value={entity.value} key={`target-entity-${entity.value}`}>
@@ -310,14 +303,9 @@ export default function GitLabCreateIntegrationPage() {
errorText={error?.message}
isError={Boolean(error)}
>
<Select
{...field}
onValueChange={(e) => onChange(e)}
className="w-full"
>
<Select {...field} onValueChange={(e) => onChange(e)} className="w-full">
{integrationAuthTeams.length > 0 ? (
integrationAuthTeams.map((integrationAuthTeam) =>
(
integrationAuthTeams.map((integrationAuthTeam) => (
<SelectItem
value={String(integrationAuthTeam.teamId as string)}
key={`target-team-${String(integrationAuthTeam.teamId)}`}
@@ -349,7 +337,7 @@ export default function GitLabCreateIntegrationPage() {
{...field}
onValueChange={(e) => {
if (e === "") return;
onChange(e)
onChange(e);
}}
className="w-full"
>
@@ -369,24 +357,22 @@ export default function GitLabCreateIntegrationPage() {
)}
</Select>
</FormControl>
)}}
/>
<Controller
control={control}
defaultValue=""
name="targetEnvironment"
render={({ field, fieldState: { error } }) => (
<FormControl
label="GitLab Environment Scope (Optional)"
isError={Boolean(error)}
errorText={error?.message}
>
<Input
{...field}
placeholder="*"
/>
</FormControl>
)}
);
}}
/>
<Controller
control={control}
defaultValue=""
name="targetEnvironment"
render={({ field, fieldState: { error } }) => (
<FormControl
label="GitLab Environment Scope (Optional)"
isError={Boolean(error)}
errorText={error?.message}
>
<Input {...field} placeholder="*" />
</FormControl>
)}
/>
</motion.div>
</TabPanel>
@@ -403,32 +389,26 @@ export default function GitLabCreateIntegrationPage() {
control={control}
name="secretPrefix"
render={({ field, fieldState: { error } }) => (
<FormControl
label="Secret Prefix"
isError={Boolean(error)}
errorText={error?.message}
>
<Input
{...field}
placeholder="INFISICAL_"
/>
</FormControl>
<FormControl
label="Secret Prefix"
isError={Boolean(error)}
errorText={error?.message}
>
<Input {...field} placeholder="INFISICAL_" />
</FormControl>
)}
/>
<Controller
control={control}
name="secretSuffix"
render={({ field, fieldState: { error } }) => (
<FormControl
label="Secret Suffix"
isError={Boolean(error)}
errorText={error?.message}
>
<Input
{...field}
placeholder="_INFISICAL"
/>
</FormControl>
<FormControl
label="Secret Suffix"
isError={Boolean(error)}
errorText={error?.message}
>
<Input {...field} placeholder="_INFISICAL" />
</FormControl>
)}
/>
</motion.div>
@@ -445,61 +425,71 @@ export default function GitLabCreateIntegrationPage() {
>
Create Integration
</Button>
</Card>
</Card>
{/* <div className="border-t border-mineshaft-800 w-full max-w-md mt-6"/>
<div className="flex flex-col bg-mineshaft-800 border border-mineshaft-600 w-full p-4 max-w-lg mt-6 rounded-md">
<div className="flex flex-row items-center"><FontAwesomeIcon icon={faCircleInfo} className="text-mineshaft-200 text-xl"/> <span className="ml-3 text-md text-mineshaft-100">Pro Tips</span></div>
<span className="text-mineshaft-300 text-sm mt-4">After creating an integration, your secrets will start syncing immediately. This might cause an unexpected override of current secrets in GitLab with secrets from Infisical.</span>
</div> */}
<Modal
isOpen={popUp.confirmIntegration?.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle("confirmIntegration", isOpen)}
isOpen={popUp.confirmIntegration?.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle("confirmIntegration", isOpen)}
>
<ModalContent
title="Heads Up"
footerContent={
<div className="flex items-center space-x-2">
<Button onClick={() => onFormSubmit(popUp.confirmIntegration?.data as FormData)}>
Continue Anyway
</Button>
<Button
onClick={() => handlePopUpClose("confirmIntegration")}
variant="outline_bg"
colorSchema="secondary"
>
Cancel
</Button>
</div>
}
>
<ModalContent
title="Heads Up"
footerContent={
<div className="flex items-center space-x-2">
<Button onClick={() => onFormSubmit(popUp.confirmIntegration?.data as FormData)}>
Continue Anyway
</Button>
<Button
onClick={() => handlePopUpClose("confirmIntegration")}
variant="outline_bg"
colorSchema="secondary"
>
Cancel
</Button>
</div>
}
>
<p>
You&apos;re about to overwrite any existing secrets in GitLab.
</p>
<p className="mt-4">
To avoid this behavior, you may consider adding a secret prefix/suffix in the options tab.
</p>
</ModalContent>
</Modal>
<p>You&apos;re about to overwrite any existing secrets in GitLab.</p>
<p className="mt-4">
To avoid this behavior, you may consider adding a secret prefix/suffix in the options
tab.
</p>
</ModalContent>
</Modal>
</form>
) : (
<div className="flex justify-center items-center w-full h-full">
<div className="flex h-full w-full items-center justify-center">
<Head>
<title>Set Up GitLab Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
{isIntegrationAuthAppsLoading || isintegrationAuthTeamsLoading ? <img src="/images/loading/loading.gif" height={70} width={120} alt="infisical loading indicator" /> : <div className="max-w-md h-max p-6 border border-mineshaft-600 rounded-md bg-mineshaft-800 text-mineshaft-200 flex flex-col text-center">
<FontAwesomeIcon icon={faBugs} className="text-6xl my-2 inlineli"/>
<p>
Something went wrong. Please contact <a
className="inline underline underline-offset-4 decoration-primary-500 opacity-80 hover:opacity-100 text-mineshaft-100 duration-200 cursor-pointer"
target="_blank"
rel="noopener noreferrer"
href="mailto:[email protected]"
>
support@infisical.com
</a> if the issue persists.
</p>
</div>}
{isIntegrationAuthAppsLoading || isintegrationAuthTeamsLoading ? (
<img
src="/images/loading/loading.gif"
height={70}
width={120}
alt="infisical loading indicator"
/>
) : (
<div className="flex h-max max-w-md flex-col rounded-md border border-mineshaft-600 bg-mineshaft-800 p-6 text-center text-mineshaft-200">
<FontAwesomeIcon icon={faBugs} className="inlineli my-2 text-6xl" />
<p>
Something went wrong. Please contact{" "}
<a
className="inline cursor-pointer text-mineshaft-100 underline decoration-primary-500 underline-offset-4 opacity-80 duration-200 hover:opacity-100"
target="_blank"
rel="noopener noreferrer"
href="mailto:[email protected]"
>
support@infisical.com
</a>{" "}
if the issue persists.
</p>
</div>
)}
</div>
);
}
@@ -2,9 +2,7 @@ import { useEffect } from "react";
import { useRouter } from "next/router";
import queryString from "query-string";
import {
useAuthorizeIntegration
} from "@app/hooks/api";
import { useAuthorizeIntegration } from "@app/hooks/api";
export default function GitLabOAuth2CallbackPage() {
const router = useRouter();
@@ -16,7 +14,7 @@ export default function GitLabOAuth2CallbackPage() {
try {
// validate state
const [csrfToken, url] = (state as string).split("|", 2);
if (csrfToken !== localStorage.getItem("latestCSRFToken")) return;
localStorage.removeItem("latestCSRFToken");
@@ -24,9 +22,11 @@ export default function GitLabOAuth2CallbackPage() {
workspaceId: localStorage.getItem("projectData.id") as string,
code: code as string,
integration: "gitlab",
...(url === "" ? {} : {
url
})
...(url === ""
? {}
: {
url
})
});
router.push(`/integrations/gitlab/create?integrationAuthId=${integrationAuth.id}`);
@@ -6,9 +6,7 @@ import { useRouter } from "next/router";
import { faArrowUpRightFromSquare, faBookOpen } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
useSaveIntegrationAccessToken
} from "@app/hooks/api";
import { useSaveIntegrationAccessToken } from "@app/hooks/api";
import { Button, Card, CardTitle, FormControl, Input } from "../../../components/v2";
@@ -18,7 +16,7 @@ export default function HashiCorpVaultAuthorizeIntegrationPage() {
const [vaultURL, setVaultURL] = useState("");
const [vaultURLErrorText, setVaultURLErrorText] = useState("");
const [vaultNamespace, setVaultNamespace] = useState("");
const [vaultNamespaceErrorText, setVaultNamespaceErrorText] = useState("");
@@ -35,44 +33,44 @@ export default function HashiCorpVaultAuthorizeIntegrationPage() {
if (vaultURL.length === 0) {
setVaultURLErrorText("Vault Cluster URL cannot be blank");
} else {
setVaultURLErrorText("");
setVaultURLErrorText("");
}
if (vaultNamespace.length === 0) {
setVaultNamespaceErrorText("Vault Namespace cannot be blank");
} else {
setVaultNamespaceErrorText("");
}
if (vaultRoleID.length === 0) {
setVaultRoleIDErrorText("Vault Role ID cannot be blank");
} else {
setVaultRoleIDErrorText("");
}
if (vaultSecretID.length === 0) {
setVaultSecretIDErrorText("Vault Secret ID cannot be blank");
} else {
setVaultSecretIDErrorText("");
}
if (
vaultURL.length === 0 ||
vaultNamespace.length === 0 ||
vaultRoleID.length === 0 ||
vaultSecretID.length === 0
vaultURL.length === 0 ||
vaultNamespace.length === 0 ||
vaultRoleID.length === 0 ||
vaultSecretID.length === 0
) {
return;
return;
}
setIsLoading(true);
const integrationAuth = await mutateAsync({
workspaceId: localStorage.getItem("projectData.id"),
integration: "hashicorp-vault",
accessId: vaultRoleID,
accessToken: vaultSecretID,
url: vaultURL,
namespace: vaultNamespace
workspaceId: localStorage.getItem("projectData.id"),
integration: "hashicorp-vault",
accessId: vaultRoleID,
accessToken: vaultSecretID,
url: vaultURL,
namespace: vaultNamespace
});
setIsLoading(false);
@@ -87,11 +85,11 @@ export default function HashiCorpVaultAuthorizeIntegrationPage() {
<div className="flex h-full w-full items-center justify-center">
<Head>
<title>Authorize Vault Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
<Card className="max-w-lg rounded-md border border-mineshaft-600 mb-12">
<CardTitle
className="text-left px-6 text-xl"
<Card className="mb-12 max-w-lg rounded-md border border-mineshaft-600">
<CardTitle
className="px-6 text-left text-xl"
subTitle="After connecting to Vault, you will be prompted to set up an integration for a particular Infisical project and environment."
>
<div className="flex flex-row items-center">
@@ -106,10 +104,13 @@ export default function HashiCorpVaultAuthorizeIntegrationPage() {
<span className="ml-2.5">HashiCorp Vault Integration</span>
<Link href="https://infisical.com/docs/integrations/cloud/hashicorp-vault" passHref>
<a target="_blank" rel="noopener noreferrer">
<div className="ml-2 mb-1 rounded-md text-yellow text-sm inline-block bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] opacity-80 hover:opacity-100 cursor-default">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5"/>
<div className="ml-2 mb-1 inline-block cursor-default rounded-md bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] text-sm text-yellow opacity-80 hover:opacity-100">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
Docs
<FontAwesomeIcon icon={faArrowUpRightFromSquare} className="ml-1.5 text-xxs mb-[0.07rem]"/>
<FontAwesomeIcon
icon={faArrowUpRightFromSquare}
className="ml-1.5 mb-[0.07rem] text-xxs"
/>
</div>
</a>
</Link>
@@ -129,11 +130,11 @@ export default function HashiCorpVaultAuthorizeIntegrationPage() {
isError={vaultNamespaceErrorText !== "" ?? false}
className="px-6"
>
<Input
placeholder="admin/education"
value={vaultNamespace}
onChange={(e) => setVaultNamespace(e.target.value)}
/>
<Input
placeholder="admin/education"
value={vaultNamespace}
onChange={(e) => setVaultNamespace(e.target.value)}
/>
</FormControl>
<FormControl
label="Vault RoleID"
@@ -141,7 +142,11 @@ export default function HashiCorpVaultAuthorizeIntegrationPage() {
isError={vaultRoleIDErrorText !== "" ?? false}
className="px-6"
>
<Input placeholder="" value={vaultRoleID} onChange={(e) => setVaultRoleID(e.target.value)} />
<Input
placeholder=""
value={vaultRoleID}
onChange={(e) => setVaultRoleID(e.target.value)}
/>
</FormControl>
<FormControl
label="Vault SecretID"
@@ -149,11 +154,11 @@ export default function HashiCorpVaultAuthorizeIntegrationPage() {
isError={vaultSecretIDErrorText !== "" ?? false}
className="px-6"
>
<Input
placeholder=""
value={vaultSecretID}
onChange={(e) => setVaultSecretID(e.target.value)}
/>
<Input
placeholder=""
value={vaultSecretID}
onChange={(e) => setVaultSecretID(e.target.value)}
/>
</FormControl>
<Button
onClick={handleButtonClick}
@@ -169,4 +174,4 @@ export default function HashiCorpVaultAuthorizeIntegrationPage() {
);
}
HashiCorpVaultAuthorizeIntegrationPage.requireAuth = true;
HashiCorpVaultAuthorizeIntegrationPage.requireAuth = true;
@@ -3,13 +3,16 @@ import Head from "next/head";
import Image from "next/image";
import Link from "next/link";
import { useRouter } from "next/router";
import { faArrowUpRightFromSquare, faBookOpen, faBugs, faCircleInfo } from "@fortawesome/free-solid-svg-icons";
import {
faArrowUpRightFromSquare,
faBookOpen,
faBugs,
faCircleInfo
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import queryString from "query-string";
import {
useCreateIntegration
} from "@app/hooks/api";
import { useCreateIntegration } from "@app/hooks/api";
import {
Button,
@@ -30,7 +33,9 @@ export default function HashiCorpVaultCreateIntegrationPage() {
const { integrationAuthId } = queryString.parse(router.asPath.split("?")[1]);
const { data: workspace } = useGetWorkspaceById(localStorage.getItem("projectData.id") ?? "");
const { data: integrationAuth, isLoading: isintegrationAuthLoading } = useGetIntegrationAuthById((integrationAuthId as string) ?? "");
const { data: integrationAuth, isLoading: isintegrationAuthLoading } = useGetIntegrationAuthById(
(integrationAuthId as string) ?? ""
);
const [vaultEnginePath, setVaultEnginePath] = useState("");
const [vaultEnginePathErrorText, setVaultEnginePathErrorText] = useState("");
@@ -84,14 +89,14 @@ export default function HashiCorpVaultCreateIntegrationPage() {
};
return integrationAuth && workspace ? (
<div className="flex flex-col h-full w-full items-center justify-center">
<div className="flex h-full w-full flex-col items-center justify-center">
<Head>
<title>Set Up Vault Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
<Card className="max-w-lg rounded-md border border-mineshaft-600">
<CardTitle
className="text-left px-6 text-xl"
<CardTitle
className="px-6 text-left text-xl"
subTitle="Select which environment or folder in Infisical you want to sync to which path in HashiCorp Vault."
>
<div className="flex flex-row items-center">
@@ -106,10 +111,13 @@ export default function HashiCorpVaultCreateIntegrationPage() {
<span className="ml-2.5">HashiCorp Vault Integration</span>
<Link href="https://infisical.com/docs/integrations/cloud/hashicorp-vault" passHref>
<a target="_blank" rel="noopener noreferrer">
<div className="ml-2 mb-1 rounded-md text-yellow text-sm inline-block bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] opacity-80 hover:opacity-100 cursor-default">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5"/>
<div className="ml-2 mb-1 inline-block cursor-default rounded-md bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] text-sm text-yellow opacity-80 hover:opacity-100">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
Docs
<FontAwesomeIcon icon={faArrowUpRightFromSquare} className="ml-1.5 text-xxs mb-[0.07rem]"/>
<FontAwesomeIcon
icon={faArrowUpRightFromSquare}
className="ml-1.5 mb-[0.07rem] text-xxs"
/>
</div>
</a>
</Link>
@@ -173,31 +181,48 @@ export default function HashiCorpVaultCreateIntegrationPage() {
Create Integration
</Button>
</Card>
<div className="border-t border-mineshaft-800 w-full max-w-md mt-6"/>
<div className="flex flex-col bg-mineshaft-800 border border-mineshaft-600 w-full p-4 max-w-lg mt-6 rounded-md">
<div className="flex flex-row items-center"><FontAwesomeIcon icon={faCircleInfo} className="text-mineshaft-200 text-xl"/> <span className="ml-3 text-md text-mineshaft-100">Pro Tips</span></div>
<span className="text-mineshaft-300 text-sm mt-4">After creating an integration, your secrets will start syncing immediately. This might cause an unexpected override of current secrets in Vault with secrets from Infisical.</span>
<div className="mt-6 w-full max-w-md border-t border-mineshaft-800" />
<div className="mt-6 flex w-full max-w-lg flex-col rounded-md border border-mineshaft-600 bg-mineshaft-800 p-4">
<div className="flex flex-row items-center">
<FontAwesomeIcon icon={faCircleInfo} className="text-xl text-mineshaft-200" />{" "}
<span className="text-md ml-3 text-mineshaft-100">Pro Tips</span>
</div>
<span className="mt-4 text-sm text-mineshaft-300">
After creating an integration, your secrets will start syncing immediately. This might
cause an unexpected override of current secrets in Vault with secrets from Infisical.
</span>
</div>
</div>
) : (
<div className="flex justify-center items-center w-full h-full">
<div className="flex h-full w-full items-center justify-center">
<Head>
<title>Set Up Vault Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
{isintegrationAuthLoading ? <img src="/images/loading/loading.gif" height={70} width={120} alt="infisical loading indicator" /> : <div className="max-w-md h-max p-6 border border-mineshaft-600 rounded-md bg-mineshaft-800 text-mineshaft-200 flex flex-col text-center">
<FontAwesomeIcon icon={faBugs} className="text-6xl my-2 inlineli"/>
<p>
Something went wrong. Please contact <a
className="inline underline underline-offset-4 decoration-primary-500 opacity-80 hover:opacity-100 text-mineshaft-100 duration-200 cursor-pointer"
target="_blank"
rel="noopener noreferrer"
href="mailto:[email protected]"
>
support@infisical.com
</a> if the issue persists.
</p>
</div>}
{isintegrationAuthLoading ? (
<img
src="/images/loading/loading.gif"
height={70}
width={120}
alt="infisical loading indicator"
/>
) : (
<div className="flex h-max max-w-md flex-col rounded-md border border-mineshaft-600 bg-mineshaft-800 p-6 text-center text-mineshaft-200">
<FontAwesomeIcon icon={faBugs} className="inlineli my-2 text-6xl" />
<p>
Something went wrong. Please contact{" "}
<a
className="inline cursor-pointer text-mineshaft-100 underline decoration-primary-500 underline-offset-4 opacity-80 duration-200 hover:opacity-100"
target="_blank"
rel="noopener noreferrer"
href="mailto:[email protected]"
>
support@infisical.com
</a>{" "}
if the issue persists.
</p>
</div>
)}
</div>
);
}
@@ -2,9 +2,7 @@ import { useEffect, useState } from "react";
import { useRouter } from "next/router";
import queryString from "query-string";
import {
useCreateIntegration
} from "@app/hooks/api";
import { useCreateIntegration } from "@app/hooks/api";
import {
Button,
@@ -2,9 +2,7 @@ import { useEffect } from "react";
import { useRouter } from "next/router";
import queryString from "query-string";
import {
useAuthorizeIntegration
} from "@app/hooks/api";
import { useAuthorizeIntegration } from "@app/hooks/api";
export default function HerokuOAuth2CallbackPage() {
const router = useRouter();
@@ -1,9 +1,7 @@
import { useState } from "react";
import { useRouter } from "next/router";
import {
useSaveIntegrationAccessToken
} from "@app/hooks/api";
import { useSaveIntegrationAccessToken } from "@app/hooks/api";
import { Button, Card, CardTitle, FormControl, Input } from "../../../components/v2";
@@ -26,7 +24,7 @@ export default function LaravelForgeCreateIntegrationPage() {
setApiKeyErrorText("Access Token cannot be blank");
return;
}
if (serverId.length === 0) {
setServerIdErrorText("Server Id cannot be blank");
return;
@@ -58,14 +56,22 @@ export default function LaravelForgeCreateIntegrationPage() {
errorText={apiKeyErrorText}
isError={apiKeyErrorText !== "" ?? false}
>
<Input placeholder="Access Token" value={apiKey} onChange={(e) => setApiKey(e.target.value)} />
<Input
placeholder="Access Token"
value={apiKey}
onChange={(e) => setApiKey(e.target.value)}
/>
</FormControl>
<FormControl
label="Laravel Forge Server ID"
errorText={serverIdErrorText}
isError={serverIdErrorText !== "" ?? false}
>
<Input placeholder="123456" value={serverId} onChange={(e) => setServerId(e.target.value)} />
<Input
placeholder="123456"
value={serverId}
onChange={(e) => setServerId(e.target.value)}
/>
</FormControl>
<Button
onClick={handleButtonClick}
@@ -2,9 +2,7 @@ import { useEffect, useState } from "react";
import { useRouter } from "next/router";
import queryString from "query-string";
import {
useCreateIntegration
} from "@app/hooks/api";
import { useCreateIntegration } from "@app/hooks/api";
import {
Button,
@@ -64,7 +62,10 @@ export default function LaravelForgeCreateIntegrationPage() {
integrationAuthId: integrationAuth?.id,
isActive: true,
app: targetApp,
appId: String(integrationAuthApps?.find((integrationAuthApp) => integrationAuthApp.name === targetApp)?.appId),
appId: String(
integrationAuthApps?.find((integrationAuthApp) => integrationAuthApp.name === targetApp)
?.appId
),
sourceEnvironment: selectedSourceEnvironment,
secretPath
});
@@ -2,9 +2,7 @@ import { useEffect, useState } from "react";
import { useRouter } from "next/router";
import queryString from "query-string";
import {
useCreateIntegration
} from "@app/hooks/api";
import { useCreateIntegration } from "@app/hooks/api";
import {
Button,
@@ -73,7 +71,9 @@ export default function NetlifyCreateIntegrationPage() {
integrationAuthId: integrationAuth?.id,
isActive: true,
app: targetApp,
appId: integrationAuthApps?.find((integrationAuthApp) => integrationAuthApp.name === targetApp)?.appId,
appId: integrationAuthApps?.find(
(integrationAuthApp) => integrationAuthApp.name === targetApp
)?.appId,
sourceEnvironment: selectedSourceEnvironment,
targetEnvironment,
secretPath
@@ -2,9 +2,7 @@ import { useEffect } from "react";
import { useRouter } from "next/router";
import queryString from "query-string";
import {
useAuthorizeIntegration
} from "@app/hooks/api";
import { useAuthorizeIntegration } from "@app/hooks/api";
export default function NetlifyOAuth2CallbackPage() {
const router = useRouter();
@@ -1,9 +1,7 @@
import { useState } from "react";
import { useRouter } from "next/router";
import {
useSaveIntegrationAccessToken
} from "@app/hooks/api";
import { useSaveIntegrationAccessToken } from "@app/hooks/api";
import { Button, Card, CardTitle, FormControl, Input } from "../../../components/v2";
@@ -2,9 +2,7 @@ import { useEffect, useState } from "react";
import { useRouter } from "next/router";
import queryString from "query-string";
import {
useCreateIntegration
} from "@app/hooks/api";
import { useCreateIntegration } from "@app/hooks/api";
import {
Button,
@@ -44,7 +42,7 @@ export default function NorthflankCreateIntegrationPage() {
integrationAuthId: (integrationAuthId as string) ?? "",
appId: targetAppId
});
useEffect(() => {
if (workspace) {
setSelectedSourceEnvironment(workspace.environments[0].slug);
@@ -62,7 +60,7 @@ export default function NorthflankCreateIntegrationPage() {
}
}
}, [integrationAuthApps]);
useEffect(() => {
if (integrationAuthSecretGroups) {
if (integrationAuthSecretGroups.length > 0) {
@@ -73,9 +71,8 @@ export default function NorthflankCreateIntegrationPage() {
setTargetSecretGroupId("none");
}
}
}, [integrationAuthSecretGroups]);
const handleButtonClick = async () => {
try {
if (!integrationAuth?.id) return;
@@ -85,7 +82,9 @@ export default function NorthflankCreateIntegrationPage() {
await mutateAsync({
integrationAuthId: integrationAuth?.id,
isActive: true,
app: integrationAuthApps?.find((integrationAuthApp) => integrationAuthApp.appId === targetAppId)?.name,
app: integrationAuthApps?.find(
(integrationAuthApp) => integrationAuthApp.appId === targetAppId
)?.name,
appId: targetAppId,
sourceEnvironment: selectedSourceEnvironment,
targetServiceId: targetSecretGroupId,
@@ -99,7 +98,7 @@ export default function NorthflankCreateIntegrationPage() {
console.error(err);
}
};
return integrationAuth &&
workspace &&
selectedSourceEnvironment &&
@@ -6,9 +6,7 @@ import { useRouter } from "next/router";
import { faArrowUpRightFromSquare, faBookOpen } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
useSaveIntegrationAccessToken
} from "@app/hooks/api";
import { useSaveIntegrationAccessToken } from "@app/hooks/api";
import { Button, Card, CardTitle, FormControl, Input } from "../../../components/v2";
@@ -48,11 +46,11 @@ export default function QoveryCreateIntegrationPage() {
<div className="flex h-full w-full items-center justify-center">
<Head>
<title>Authorize Qovery Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
<Card className="max-w-lg rounded-md border border-mineshaft-600 mb-12">
<CardTitle
className="text-left px-6 text-xl"
<Card className="mb-12 max-w-lg rounded-md border border-mineshaft-600">
<CardTitle
className="px-6 text-left text-xl"
subTitle="After adding your API key, you will be prompted to set up an integration for a particular Infisical project and environment."
>
<div className="flex flex-row items-center">
@@ -67,10 +65,13 @@ export default function QoveryCreateIntegrationPage() {
<span className="ml-2.5">Qovery Integration </span>
<Link href="https://infisical.com/docs/integrations/cloud/qovery" passHref>
<a target="_blank" rel="noopener noreferrer">
<div className="ml-2 mb-1 rounded-md text-yellow text-sm inline-block bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] opacity-80 hover:opacity-100 cursor-default">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5"/>
<div className="ml-2 mb-1 inline-block cursor-default rounded-md bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] text-sm text-yellow opacity-80 hover:opacity-100">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
Docs
<FontAwesomeIcon icon={faArrowUpRightFromSquare} className="ml-1.5 text-xxs mb-[0.07rem]"/>
<FontAwesomeIcon
icon={faArrowUpRightFromSquare}
className="ml-1.5 mb-[0.07rem] text-xxs"
/>
</div>
</a>
</Link>
+165 -138
View File
@@ -21,14 +21,12 @@ import {
TabPanel,
Tabs
} from "@app/components/v2";
import { useCreateIntegration } from "@app/hooks/api";
import {
useCreateIntegration
} from "@app/hooks/api";
import {
useGetIntegrationAuthQoveryEnvironments,
useGetIntegrationAuthQoveryOrgs,
useGetIntegrationAuthQoveryProjects,
useGetIntegrationAuthQoveryScopes
useGetIntegrationAuthQoveryEnvironments,
useGetIntegrationAuthQoveryOrgs,
useGetIntegrationAuthQoveryProjects,
useGetIntegrationAuthQoveryScopes
} from "@app/hooks/api/integrationAuth/queries";
import { useGetIntegrationAuthById } from "../../../hooks/api/integrationAuth";
@@ -52,7 +50,7 @@ enum TabSections {
* -> Get projects belonging to the organization - select project
* -> Get environments belonging to the project - select environmnet
* -> Get qovery scopes / application (this is the application to sync to)
*
*
* Do we even need to get organizations?
*/
@@ -69,9 +67,11 @@ export default function QoveryCreateIntegrationPage() {
const [selectedSourceEnvironment, setSelectedSourceEnvironment] = useState("");
const [secretPath, setSecretPath] = useState("/");
const { data: integrationAuthOrgs } = useGetIntegrationAuthQoveryOrgs((integrationAuthId as string) ?? "");
const { data: integrationAuthOrgs } = useGetIntegrationAuthQoveryOrgs(
(integrationAuthId as string) ?? ""
);
const [targetOrgId, setTargetOrgId] = useState("");
const { data: integrationAuthProjects } = useGetIntegrationAuthQoveryProjects({
integrationAuthId: (integrationAuthId as string) ?? "",
orgId: targetOrgId
@@ -84,11 +84,12 @@ export default function QoveryCreateIntegrationPage() {
});
const [targetEnvironmentId, setTargetEnvironmentId] = useState("");
const { data: integrationAuthApps, isLoading: isIntegrationAuthAppsLoading } = useGetIntegrationAuthQoveryScopes({
integrationAuthId: (integrationAuthId as string) ?? "",
environmentId: targetEnvironmentId,
scope: (scope as ("job" | "application" | "container"))
});
const { data: integrationAuthApps, isLoading: isIntegrationAuthAppsLoading } =
useGetIntegrationAuthQoveryScopes({
integrationAuthId: (integrationAuthId as string) ?? "",
environmentId: targetEnvironmentId,
scope: scope as "job" | "application" | "container"
});
const [targetAppId, setTargetAppId] = useState("");
const [isLoading, setIsLoading] = useState(false);
@@ -145,10 +146,19 @@ export default function QoveryCreateIntegrationPage() {
setIsLoading(true);
const targetOrg = integrationAuthOrgs?.find((integrationAuthOrg) => integrationAuthOrg.orgId === targetOrgId)?.name;
const targetProject = integrationAuthProjects?.find((integrationAuthProject) => integrationAuthProject.projectId === targetProjectId)?.name;
const targetEnvironment = integrationAuthEnvironments?.find((integrationAuthEnvironment) => integrationAuthEnvironment.environmentId === targetEnvironmentId)?.name;
const targetApp = integrationAuthApps?.find((integrationAuthApp) => integrationAuthApp.appId === targetAppId)?.name;
const targetOrg = integrationAuthOrgs?.find(
(integrationAuthOrg) => integrationAuthOrg.orgId === targetOrgId
)?.name;
const targetProject = integrationAuthProjects?.find(
(integrationAuthProject) => integrationAuthProject.projectId === targetProjectId
)?.name;
const targetEnvironment = integrationAuthEnvironments?.find(
(integrationAuthEnvironment) =>
integrationAuthEnvironment.environmentId === targetEnvironmentId
)?.name;
const targetApp = integrationAuthApps?.find(
(integrationAuthApp) => integrationAuthApp.appId === targetAppId
)?.name;
await mutateAsync({
integrationAuthId: integrationAuth?.id,
@@ -172,18 +182,16 @@ export default function QoveryCreateIntegrationPage() {
console.error(err);
}
};
return integrationAuth &&
workspace &&
selectedSourceEnvironment ? (
<div className="flex flex-col h-full w-full items-center justify-center bg-gradient-to-tr from-mineshaft-900 to-bunker-900">
return integrationAuth && workspace && selectedSourceEnvironment ? (
<div className="flex h-full w-full flex-col items-center justify-center bg-gradient-to-tr from-mineshaft-900 to-bunker-900">
<Head>
<title>Set Up Qovery Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
<Card className="max-w-lg rounded-md border border-mineshaft-600 p-0">
<CardTitle
className="text-left px-6 text-xl"
<CardTitle
className="px-6 text-left text-xl"
subTitle="Choose which environment in Infisical you want to sync to Checkly environment variables."
>
<div className="flex flex-row items-center">
@@ -198,10 +206,13 @@ export default function QoveryCreateIntegrationPage() {
<span className="ml-2.5">Qovery Integration </span>
<Link href="https://infisical.com/docs/integrations/cloud/qovery" passHref>
<a target="_blank" rel="noopener noreferrer">
<div className="ml-2 mb-1 rounded-md text-yellow text-sm inline-block bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] opacity-80 hover:opacity-100 cursor-default">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5"/>
<div className="ml-2 mb-1 inline-block cursor-default rounded-md bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] text-sm text-yellow opacity-80 hover:opacity-100">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
Docs
<FontAwesomeIcon icon={faArrowUpRightFromSquare} className="ml-1.5 text-xxs mb-[0.07rem]"/>
<FontAwesomeIcon
icon={faArrowUpRightFromSquare}
className="ml-1.5 mb-[0.07rem] text-xxs"
/>
</div>
</a>
</Link>
@@ -209,7 +220,7 @@ export default function QoveryCreateIntegrationPage() {
</CardTitle>
<Tabs defaultValue={TabSections.InfisicalSettings} className="px-6">
<TabList>
<div className="flex flex-row border-b border-mineshaft-600 w-full">
<div className="flex w-full flex-row border-b border-mineshaft-600">
<Tab value={TabSections.InfisicalSettings}>Infisical Settings</Tab>
<Tab value={TabSections.QoverySettings}>Qovery Settings</Tab>
</div>
@@ -262,107 +273,112 @@ export default function QoveryCreateIntegrationPage() {
className="w-full border border-mineshaft-500"
>
{qoveryScopes.map((qoveryScope) => (
<SelectItem
value={qoveryScope.value}
key={`target-app-${qoveryScope.value}`}
>
<SelectItem value={qoveryScope.value} key={`target-app-${qoveryScope.value}`}>
{qoveryScope.label}
</SelectItem>
))}
</Select>
</FormControl>
{integrationAuthOrgs && <FormControl label="Qovery Organization">
<Select
value={targetOrgId}
onValueChange={(val) => setTargetOrgId(val)}
className="w-full border border-mineshaft-500"
isDisabled={integrationAuthOrgs.length === 0}
>
{integrationAuthOrgs.length > 0 ? (
integrationAuthOrgs.map((integrationAuthOrg) => (
<SelectItem
value={integrationAuthOrg.orgId}
key={`target-app-${integrationAuthOrg.orgId}`}
>
{integrationAuthOrg.name}
{integrationAuthOrgs && (
<FormControl label="Qovery Organization">
<Select
value={targetOrgId}
onValueChange={(val) => setTargetOrgId(val)}
className="w-full border border-mineshaft-500"
isDisabled={integrationAuthOrgs.length === 0}
>
{integrationAuthOrgs.length > 0 ? (
integrationAuthOrgs.map((integrationAuthOrg) => (
<SelectItem
value={integrationAuthOrg.orgId}
key={`target-app-${integrationAuthOrg.orgId}`}
>
{integrationAuthOrg.name}
</SelectItem>
))
) : (
<SelectItem value="none" key="target-app-none">
No organizaztions found
</SelectItem>
))
) : (
<SelectItem value="none" key="target-app-none">
No organizaztions found
</SelectItem>
)}
</Select>
</FormControl>}
{integrationAuthProjects && <FormControl label="Qovery Project">
<Select
value={targetProjectId}
onValueChange={(val) => setTargetProjectId(val)}
className="w-full border border-mineshaft-500"
isDisabled={integrationAuthProjects.length === 0}
>
{integrationAuthProjects.length > 0 ? (
integrationAuthProjects.map((integrationAuthProject) => (
<SelectItem
value={integrationAuthProject.projectId}
key={`target-app-${integrationAuthProject.projectId}`}
>
{integrationAuthProject.name}
)}
</Select>
</FormControl>
)}
{integrationAuthProjects && (
<FormControl label="Qovery Project">
<Select
value={targetProjectId}
onValueChange={(val) => setTargetProjectId(val)}
className="w-full border border-mineshaft-500"
isDisabled={integrationAuthProjects.length === 0}
>
{integrationAuthProjects.length > 0 ? (
integrationAuthProjects.map((integrationAuthProject) => (
<SelectItem
value={integrationAuthProject.projectId}
key={`target-app-${integrationAuthProject.projectId}`}
>
{integrationAuthProject.name}
</SelectItem>
))
) : (
<SelectItem value="none" key="target-app-none">
No projects found
</SelectItem>
))
) : (
<SelectItem value="none" key="target-app-none">
No projects found
</SelectItem>
)}
</Select>
</FormControl>}
{integrationAuthEnvironments && <FormControl label="Qovery Environment">
<Select
value={targetEnvironmentId}
onValueChange={(val) => setTargetEnvironmentId(val)}
className="w-full border border-mineshaft-500"
isDisabled={integrationAuthEnvironments.length === 0}
>
{integrationAuthEnvironments.length > 0 ? (
integrationAuthEnvironments.map((integrationAuthEnvironment) => (
<SelectItem
value={integrationAuthEnvironment.environmentId}
key={`target-app-${integrationAuthEnvironment.environmentId}`}
>
{integrationAuthEnvironment.name}
)}
</Select>
</FormControl>
)}
{integrationAuthEnvironments && (
<FormControl label="Qovery Environment">
<Select
value={targetEnvironmentId}
onValueChange={(val) => setTargetEnvironmentId(val)}
className="w-full border border-mineshaft-500"
isDisabled={integrationAuthEnvironments.length === 0}
>
{integrationAuthEnvironments.length > 0 ? (
integrationAuthEnvironments.map((integrationAuthEnvironment) => (
<SelectItem
value={integrationAuthEnvironment.environmentId}
key={`target-app-${integrationAuthEnvironment.environmentId}`}
>
{integrationAuthEnvironment.name}
</SelectItem>
))
) : (
<SelectItem value="none" key="target-app-none">
No environments found
</SelectItem>
))
) : (
<SelectItem value="none" key="target-app-none">
No environments found
</SelectItem>
)}
</Select>
</FormControl>}
{(scope && integrationAuthApps) && <FormControl label={`Qovery ${scope.charAt(0).toUpperCase() + scope.slice(1)}`}>
<Select
value={targetAppId}
onValueChange={(val) => setTargetAppId(val)}
className="w-full border border-mineshaft-500"
isDisabled={integrationAuthApps.length === 0}
>
{integrationAuthApps.length > 0 ? (
integrationAuthApps.map((integrationAuthApp) => (
<SelectItem
value={(integrationAuthApp.appId as string)}
key={`target-app-${integrationAuthApp.appId}`}
>
{integrationAuthApp.name}
)}
</Select>
</FormControl>
)}
{scope && integrationAuthApps && (
<FormControl label={`Qovery ${scope.charAt(0).toUpperCase() + scope.slice(1)}`}>
<Select
value={targetAppId}
onValueChange={(val) => setTargetAppId(val)}
className="w-full border border-mineshaft-500"
isDisabled={integrationAuthApps.length === 0}
>
{integrationAuthApps.length > 0 ? (
integrationAuthApps.map((integrationAuthApp) => (
<SelectItem
value={integrationAuthApp.appId as string}
key={`target-app-${integrationAuthApp.appId}`}
>
{integrationAuthApp.name}
</SelectItem>
))
) : (
<SelectItem value="none" key="target-app-none">
No {scope}s found
</SelectItem>
))
) : (
<SelectItem value="none" key="target-app-none">
No {scope}s found
</SelectItem>
)}
</Select>
</FormControl>}
)}
</Select>
</FormControl>
)}
</motion.div>
</TabPanel>
</Tabs>
@@ -384,24 +400,35 @@ export default function QoveryCreateIntegrationPage() {
</div> */}
</div>
) : (
<div className="flex justify-center items-center w-full h-full">
<div className="flex h-full w-full items-center justify-center">
<Head>
<title>Set Up Qovery Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
{isIntegrationAuthAppsLoading ? <img src="/images/loading/loading.gif" height={70} width={120} alt="infisical loading indicator" /> : <div className="max-w-md h-max p-6 border border-mineshaft-600 rounded-md bg-mineshaft-800 text-mineshaft-200 flex flex-col text-center">
<FontAwesomeIcon icon={faBugs} className="text-6xl my-2 inlineli"/>
<p>
Something went wrong. Please contact <a
className="inline underline underline-offset-4 decoration-primary-500 opacity-80 hover:opacity-100 text-mineshaft-100 duration-200 cursor-pointer"
target="_blank"
rel="noopener noreferrer"
href="mailto:[email protected]"
>
support@infisical.com
</a> if the issue persists.
</p>
</div>}
{isIntegrationAuthAppsLoading ? (
<img
src="/images/loading/loading.gif"
height={70}
width={120}
alt="infisical loading indicator"
/>
) : (
<div className="flex h-max max-w-md flex-col rounded-md border border-mineshaft-600 bg-mineshaft-800 p-6 text-center text-mineshaft-200">
<FontAwesomeIcon icon={faBugs} className="inlineli my-2 text-6xl" />
<p>
Something went wrong. Please contact{" "}
<a
className="inline cursor-pointer text-mineshaft-100 underline decoration-primary-500 underline-offset-4 opacity-80 duration-200 hover:opacity-100"
target="_blank"
rel="noopener noreferrer"
href="mailto:[email protected]"
>
support@infisical.com
</a>{" "}
if the issue persists.
</p>
</div>
)}
</div>
);
}
@@ -1,9 +1,7 @@
import { useState } from "react";
import { useRouter } from "next/router";
import {
useSaveIntegrationAccessToken
} from "@app/hooks/api";
import { useSaveIntegrationAccessToken } from "@app/hooks/api";
import { Button, Card, CardTitle, FormControl, Input } from "../../../components/v2";
@@ -2,9 +2,7 @@ import { useEffect, useState } from "react";
import { useRouter } from "next/router";
import queryString from "query-string";
import {
useCreateIntegration
} from "@app/hooks/api";
import { useCreateIntegration } from "@app/hooks/api";
import {
Button,
@@ -6,7 +6,7 @@ import { useRouter } from "next/router";
import { faArrowUpRightFromSquare, faBookOpen } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useSaveIntegrationAccessToken} from "@app/hooks/api";
import { useSaveIntegrationAccessToken } from "@app/hooks/api";
import { Button, Card, CardTitle, FormControl, Input } from "../../../components/v2";
@@ -46,11 +46,11 @@ export default function RenderCreateIntegrationPage() {
<div className="flex h-full w-full items-center justify-center">
<Head>
<title>Authorize Render Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
<Card className="max-w-lg rounded-md border border-mineshaft-600 mb-12">
<CardTitle
className="text-left px-6 text-xl"
<Card className="mb-12 max-w-lg rounded-md border border-mineshaft-600">
<CardTitle
className="px-6 text-left text-xl"
subTitle="After adding your API key, you will be prompted to set up an integration for a particular Infisical project and environment."
>
<div className="flex flex-row items-center">
@@ -65,10 +65,13 @@ export default function RenderCreateIntegrationPage() {
<span className="ml-2.5">Render Integration </span>
<Link href="https://infisical.com/docs/integrations/cloud/render" passHref>
<a target="_blank" rel="noopener noreferrer">
<div className="ml-2 mb-1 rounded-md text-yellow text-sm inline-block bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] opacity-80 hover:opacity-100 cursor-default">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5"/>
<div className="ml-2 mb-1 inline-block cursor-default rounded-md bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] text-sm text-yellow opacity-80 hover:opacity-100">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
Docs
<FontAwesomeIcon icon={faArrowUpRightFromSquare} className="ml-1.5 text-xxs mb-[0.07rem]"/>
<FontAwesomeIcon
icon={faArrowUpRightFromSquare}
className="ml-1.5 mb-[0.07rem] text-xxs"
/>
</div>
</a>
</Link>
@@ -3,13 +3,16 @@ import Head from "next/head";
import Image from "next/image";
import Link from "next/link";
import { useRouter } from "next/router";
import { faArrowUpRightFromSquare, faBookOpen, faBugs, faCircleInfo } from "@fortawesome/free-solid-svg-icons";
import {
faArrowUpRightFromSquare,
faBookOpen,
faBugs,
faCircleInfo
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import queryString from "query-string";
import {
useCreateIntegration
} from "@app/hooks/api";
import { useCreateIntegration } from "@app/hooks/api";
import {
Button,
@@ -33,10 +36,13 @@ export default function RenderCreateIntegrationPage() {
const { integrationAuthId } = queryString.parse(router.asPath.split("?")[1]);
const { data: workspace } = useGetWorkspaceById(localStorage.getItem("projectData.id") ?? "");
const { data: integrationAuth, isLoading: isIntegrationAuthLoading } = useGetIntegrationAuthById((integrationAuthId as string) ?? "");
const { data: integrationAuthApps, isLoading: isIntegrationAuthAppsLoading } = useGetIntegrationAuthApps({
integrationAuthId: (integrationAuthId as string) ?? ""
});
const { data: integrationAuth, isLoading: isIntegrationAuthLoading } = useGetIntegrationAuthById(
(integrationAuthId as string) ?? ""
);
const { data: integrationAuthApps, isLoading: isIntegrationAuthAppsLoading } =
useGetIntegrationAuthApps({
integrationAuthId: (integrationAuthId as string) ?? ""
});
const [selectedSourceEnvironment, setSelectedSourceEnvironment] = useState("");
const [targetApp, setTargetApp] = useState("");
@@ -69,7 +75,9 @@ export default function RenderCreateIntegrationPage() {
integrationAuthId: integrationAuth?.id,
isActive: true,
app: targetApp,
appId: integrationAuthApps?.find((integrationAuthApp) => integrationAuthApp.name === targetApp)?.appId,
appId: integrationAuthApps?.find(
(integrationAuthApp) => integrationAuthApp.name === targetApp
)?.appId,
sourceEnvironment: selectedSourceEnvironment,
secretPath
});
@@ -87,14 +95,14 @@ export default function RenderCreateIntegrationPage() {
selectedSourceEnvironment &&
integrationAuthApps &&
targetApp ? (
<div className="flex flex-col h-full w-full items-center justify-center">
<div className="flex h-full w-full flex-col items-center justify-center">
<Head>
<title>Set Up Render Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
<Card className="max-w-lg rounded-md border border-mineshaft-600">
<CardTitle
className="text-left px-6 text-xl"
<CardTitle
className="px-6 text-left text-xl"
subTitle="Choose which environment or folder in Infisical you want to sync to Render environment variables."
>
<div className="flex flex-row items-center">
@@ -109,10 +117,13 @@ export default function RenderCreateIntegrationPage() {
<span className="ml-2.5">Render Integration </span>
<Link href="https://infisical.com/docs/integrations/cloud/render" passHref>
<a target="_blank" rel="noopener noreferrer">
<div className="ml-2 mb-1 rounded-md text-yellow text-sm inline-block bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] opacity-80 hover:opacity-100 cursor-default">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5"/>
<div className="ml-2 mb-1 inline-block cursor-default rounded-md bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] text-sm text-yellow opacity-80 hover:opacity-100">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
Docs
<FontAwesomeIcon icon={faArrowUpRightFromSquare} className="ml-1.5 text-xxs mb-[0.07rem]"/>
<FontAwesomeIcon
icon={faArrowUpRightFromSquare}
className="ml-1.5 mb-[0.07rem] text-xxs"
/>
</div>
</a>
</Link>
@@ -175,31 +186,48 @@ export default function RenderCreateIntegrationPage() {
Create Integration
</Button>
</Card>
<div className="border-t border-mineshaft-800 w-full max-w-md mt-6"/>
<div className="flex flex-col bg-mineshaft-800 border border-mineshaft-600 w-full p-4 max-w-lg mt-6 rounded-md">
<div className="flex flex-row items-center"><FontAwesomeIcon icon={faCircleInfo} className="text-mineshaft-200 text-xl"/> <span className="ml-3 text-md text-mineshaft-100">Pro Tips</span></div>
<span className="text-mineshaft-300 text-sm mt-4">After creating an integration, your secrets will start syncing immediately. This might cause an unexpected override of current secrets in Render with secrets from Infisical.</span>
<div className="mt-6 w-full max-w-md border-t border-mineshaft-800" />
<div className="mt-6 flex w-full max-w-lg flex-col rounded-md border border-mineshaft-600 bg-mineshaft-800 p-4">
<div className="flex flex-row items-center">
<FontAwesomeIcon icon={faCircleInfo} className="text-xl text-mineshaft-200" />{" "}
<span className="text-md ml-3 text-mineshaft-100">Pro Tips</span>
</div>
<span className="mt-4 text-sm text-mineshaft-300">
After creating an integration, your secrets will start syncing immediately. This might
cause an unexpected override of current secrets in Render with secrets from Infisical.
</span>
</div>
</div>
) : (
<div className="flex justify-center items-center w-full h-full">
<div className="flex h-full w-full items-center justify-center">
<Head>
<title>Set Up Render Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
{isIntegrationAuthLoading || isIntegrationAuthAppsLoading ? <img src="/images/loading/loading.gif" height={70} width={120} alt="infisical loading indicator" /> : <div className="max-w-md h-max p-6 border border-mineshaft-600 rounded-md bg-mineshaft-800 text-mineshaft-200 flex flex-col text-center">
<FontAwesomeIcon icon={faBugs} className="text-6xl my-2 inlineli"/>
<p>
Something went wrong. Please contact <a
className="inline underline underline-offset-4 decoration-primary-500 opacity-80 hover:opacity-100 text-mineshaft-100 duration-200 cursor-pointer"
target="_blank"
rel="noopener noreferrer"
href="mailto:[email protected]"
>
support@infisical.com
</a> if the issue persists.
</p>
</div>}
{isIntegrationAuthLoading || isIntegrationAuthAppsLoading ? (
<img
src="/images/loading/loading.gif"
height={70}
width={120}
alt="infisical loading indicator"
/>
) : (
<div className="flex h-max max-w-md flex-col rounded-md border border-mineshaft-600 bg-mineshaft-800 p-6 text-center text-mineshaft-200">
<FontAwesomeIcon icon={faBugs} className="inlineli my-2 text-6xl" />
<p>
Something went wrong. Please contact{" "}
<a
className="inline cursor-pointer text-mineshaft-100 underline decoration-primary-500 underline-offset-4 opacity-80 duration-200 hover:opacity-100"
target="_blank"
rel="noopener noreferrer"
href="mailto:[email protected]"
>
support@infisical.com
</a>{" "}
if the issue persists.
</p>
</div>
)}
</div>
);
}
@@ -1,9 +1,7 @@
import { useState } from "react";
import { useRouter } from "next/router";
import {
useSaveIntegrationAccessToken
} from "@app/hooks/api";
import { useSaveIntegrationAccessToken } from "@app/hooks/api";
import { Button, Card, CardTitle, FormControl, Input } from "../../../components/v2";
@@ -2,9 +2,7 @@ import { useEffect, useState } from "react";
import { useRouter } from "next/router";
import queryString from "query-string";
import {
useCreateIntegration
} from "@app/hooks/api";
import { useCreateIntegration } from "@app/hooks/api";
import {
Button,
@@ -65,7 +63,9 @@ export default function SupabaseCreateIntegrationPage() {
integrationAuthId: integrationAuth?.id,
isActive: true,
app: targetApp,
appId: integrationAuthApps?.find((integrationAuthApp) => integrationAuthApp.name === targetApp)?.appId,
appId: integrationAuthApps?.find(
(integrationAuthApp) => integrationAuthApp.name === targetApp
)?.appId,
sourceEnvironment: selectedSourceEnvironment,
secretPath
});
@@ -6,9 +6,7 @@ import { useRouter } from "next/router";
import { faArrowUpRightFromSquare, faBookOpen } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
useSaveIntegrationAccessToken
} from "@app/hooks/api";
import { useSaveIntegrationAccessToken } from "@app/hooks/api";
import { Button, Card, CardTitle, FormControl, Input } from "../../../components/v2";
@@ -43,7 +41,7 @@ export default function TeamCityCreateIntegrationPage() {
workspaceId: localStorage.getItem("projectData.id"),
integration: "teamcity",
accessToken: apiKey,
url: serverUrl,
url: serverUrl
});
setIsLoading(false);
@@ -58,11 +56,11 @@ export default function TeamCityCreateIntegrationPage() {
<div className="flex h-full w-full items-center justify-center">
<Head>
<title>Authorize TeamCity Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
<Card className="max-w-lg rounded-md border border-mineshaft-600 mb-12">
<CardTitle
className="text-left px-6 text-xl"
<Card className="mb-12 max-w-lg rounded-md border border-mineshaft-600">
<CardTitle
className="px-6 text-left text-xl"
subTitle="After adding the details below, you will be prompted to set up an integration for a particular Infisical project and environment."
>
<div className="flex flex-row items-center">
@@ -77,10 +75,13 @@ export default function TeamCityCreateIntegrationPage() {
<span className="ml-2">TeamCity Integration</span>
<Link href="https://infisical.com/docs/integrations/cloud/teamcity" passHref>
<a target="_blank" rel="noopener noreferrer">
<div className="ml-2 mb-1 rounded-md text-yellow text-sm inline-block bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] opacity-80 hover:opacity-100 cursor-default">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5"/>
<div className="ml-2 mb-1 inline-block cursor-default rounded-md bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] text-sm text-yellow opacity-80 hover:opacity-100">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
Docs
<FontAwesomeIcon icon={faArrowUpRightFromSquare} className="ml-1.5 text-xxs mb-[0.07rem]"/>
<FontAwesomeIcon
icon={faArrowUpRightFromSquare}
className="ml-1.5 mb-[0.07rem] text-xxs"
/>
</div>
</a>
</Link>
@@ -7,9 +7,7 @@ import { faArrowUpRightFromSquare, faBookOpen, faBugs } from "@fortawesome/free-
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import queryString from "query-string";
import {
useCreateIntegration
} from "@app/hooks/api";
import { useCreateIntegration } from "@app/hooks/api";
import {
Button,
@@ -30,7 +28,7 @@ import { useGetWorkspaceById } from "../../../hooks/api/workspace";
export default function TeamCityCreateIntegrationPage() {
const router = useRouter();
const { mutateAsync } = useCreateIntegration();
const [selectedSourceEnvironment, setSelectedSourceEnvironment] = useState("");
const [targetAppId, setTargetAppId] = useState("");
const [targetBuildConfigId, setTargetBuildConfigId] = useState<string>("");
@@ -40,16 +38,19 @@ export default function TeamCityCreateIntegrationPage() {
const { integrationAuthId } = queryString.parse(router.asPath.split("?")[1]);
const { data: workspace } = useGetWorkspaceById(localStorage.getItem("projectData.id") ?? "");
const { data: integrationAuth, isLoading: isIntegrationAuthLoading } = useGetIntegrationAuthById((integrationAuthId as string) ?? "");
const { data: integrationAuthApps, isLoading: isIntegrationAuthAppsLoading } = useGetIntegrationAuthApps({
integrationAuthId: (integrationAuthId as string) ?? ""
});
const { data: integrationAuth, isLoading: isIntegrationAuthLoading } = useGetIntegrationAuthById(
(integrationAuthId as string) ?? ""
);
const { data: integrationAuthApps, isLoading: isIntegrationAuthAppsLoading } =
useGetIntegrationAuthApps({
integrationAuthId: (integrationAuthId as string) ?? ""
});
const { data: targetBuildConfigs } = useGetIntegrationAuthTeamCityBuildConfigs({
integrationAuthId: (integrationAuthId as string) ?? "",
appId: targetAppId
});
useEffect(() => {
if (workspace) {
setSelectedSourceEnvironment(workspace.environments[0].slug);
@@ -65,21 +66,23 @@ export default function TeamCityCreateIntegrationPage() {
}
}
}, [integrationAuthApps]);
const handleButtonClick = async () => {
try {
if (!integrationAuth?.id) return;
setIsLoading(true);
const targetEnvironment = targetBuildConfigs?.find(
(buildConfig) => buildConfig.buildConfigId === targetBuildConfigId
);
await mutateAsync({
integrationAuthId: integrationAuth?.id,
isActive: true,
app: integrationAuthApps?.find((integrationAuthApp) => integrationAuthApp.appId === targetAppId)?.name,
app: integrationAuthApps?.find(
(integrationAuthApp) => integrationAuthApp.appId === targetAppId
)?.name,
appId: targetAppId,
sourceEnvironment: selectedSourceEnvironment,
targetEnvironment: targetEnvironment?.name,
@@ -109,11 +112,11 @@ export default function TeamCityCreateIntegrationPage() {
<div className="flex h-full w-full items-center justify-center">
<Head>
<title>Set Up TeamCity Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
<Card className="max-w-lg rounded-md border border-mineshaft-600 mb-12">
<CardTitle
className="text-left px-6 text-xl"
<Card className="mb-12 max-w-lg rounded-md border border-mineshaft-600">
<CardTitle
className="px-6 text-left text-xl"
subTitle="Choose which environment or folders in Infisical you want to sync to which project in TeamCity."
>
<div className="flex flex-row items-center">
@@ -128,10 +131,13 @@ export default function TeamCityCreateIntegrationPage() {
<span className="ml-2">TeamCity Integration</span>
<Link href="https://infisical.com/docs/integrations/cloud/teamcity" passHref>
<a target="_blank" rel="noopener noreferrer">
<div className="ml-2 mb-1 rounded-md text-yellow text-sm inline-block bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] opacity-80 hover:opacity-100 cursor-default">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5"/>
<div className="ml-2 mb-1 inline-block cursor-default rounded-md bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] text-sm text-yellow opacity-80 hover:opacity-100">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
Docs
<FontAwesomeIcon icon={faArrowUpRightFromSquare} className="ml-1.5 text-xxs mb-[0.07rem]"/>
<FontAwesomeIcon
icon={faArrowUpRightFromSquare}
className="ml-1.5 mb-[0.07rem] text-xxs"
/>
</div>
</a>
</Link>
@@ -183,7 +189,7 @@ export default function TeamCityCreateIntegrationPage() {
)}
</Select>
</FormControl>
<FormControl label="Team City Build Config (Optional)" className="px-6">
<FormControl label="Team City Build Config (Optional)" className="px-6">
<Select
value={targetBuildConfigId}
onValueChange={(val) => setTargetBuildConfigId(val)}
@@ -212,24 +218,35 @@ export default function TeamCityCreateIntegrationPage() {
</Card>
</div>
) : (
<div className="flex justify-center items-center w-full h-full">
<div className="flex h-full w-full items-center justify-center">
<Head>
<title>Set Up TeamCity Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
{isIntegrationAuthLoading || isIntegrationAuthAppsLoading ? <img src="/images/loading/loading.gif" height={70} width={120} alt="infisical loading indicator" /> : <div className="max-w-md h-max p-6 border border-mineshaft-600 rounded-md bg-mineshaft-800 text-mineshaft-200 flex flex-col text-center">
<FontAwesomeIcon icon={faBugs} className="text-6xl my-2 inlineli"/>
<p>
Something went wrong. Please contact <a
className="inline underline underline-offset-4 decoration-primary-500 opacity-80 hover:opacity-100 text-mineshaft-100 duration-200 cursor-pointer"
target="_blank"
rel="noopener noreferrer"
href="mailto:[email protected]"
>
support@infisical.com
</a> if the issue persists.
</p>
</div>}
{isIntegrationAuthLoading || isIntegrationAuthAppsLoading ? (
<img
src="/images/loading/loading.gif"
height={70}
width={120}
alt="infisical loading indicator"
/>
) : (
<div className="flex h-max max-w-md flex-col rounded-md border border-mineshaft-600 bg-mineshaft-800 p-6 text-center text-mineshaft-200">
<FontAwesomeIcon icon={faBugs} className="inlineli my-2 text-6xl" />
<p>
Something went wrong. Please contact{" "}
<a
className="inline cursor-pointer text-mineshaft-100 underline decoration-primary-500 underline-offset-4 opacity-80 duration-200 hover:opacity-100"
target="_blank"
rel="noopener noreferrer"
href="mailto:[email protected]"
>
support@infisical.com
</a>{" "}
if the issue persists.
</p>
</div>
)}
</div>
);
}
@@ -1,9 +1,7 @@
import { useState } from "react";
import { useRouter } from "next/router";
import {
useSaveIntegrationAccessToken
} from "@app/hooks/api";
import { useSaveIntegrationAccessToken } from "@app/hooks/api";
import { Button, Card, CardTitle, FormControl, Input } from "../../../components/v2";
@@ -26,7 +24,7 @@ export default function TerraformCloudCreateIntegrationPage() {
setApiKeyErrorText("API Token cannot be blank");
return;
}
if (workspacesId.length === 0) {
setWorkspacesIdErrorText("Workspace Id cannot be blank");
return;
@@ -58,14 +56,22 @@ export default function TerraformCloudCreateIntegrationPage() {
errorText={apiKeyErrorText}
isError={apiKeyErrorText !== "" ?? false}
>
<Input placeholder="API Token" value={apiKey} onChange={(e) => setApiKey(e.target.value)} />
<Input
placeholder="API Token"
value={apiKey}
onChange={(e) => setApiKey(e.target.value)}
/>
</FormControl>
<FormControl
label="Terraform Cloud Workspace ID"
errorText={workspacesIdErrorText}
isError={workspacesIdErrorText !== "" ?? false}
>
<Input placeholder="Workspace Id" value={workspacesId} onChange={(e) => setWorkSpacesId(e.target.value)} />
<Input
placeholder="Workspace Id"
value={workspacesId}
onChange={(e) => setWorkSpacesId(e.target.value)}
/>
</FormControl>
<Button
onClick={handleButtonClick}
@@ -19,10 +19,7 @@ import {
} from "../../../hooks/api/integrationAuth";
import { useGetWorkspaceById } from "../../../hooks/api/workspace";
const variableTypes = [
{ name: "env" },
{ name: "terraform" }
];
const variableTypes = [{ name: "env" }, { name: "terraform" }];
export default function TerraformCloudCreateIntegrationPage() {
const router = useRouter();
@@ -65,9 +62,9 @@ export default function TerraformCloudCreateIntegrationPage() {
if (!integrationAuth?.id) return;
setVariableTypeErrorText("");
if (variableType.length === 0 ) {
setVariableTypeErrorText("Variable Type cannot be blank!")
return;
if (variableType.length === 0) {
setVariableTypeErrorText("Variable Type cannot be blank!");
return;
}
setIsLoading(true);
@@ -76,7 +73,9 @@ export default function TerraformCloudCreateIntegrationPage() {
integrationAuthId: integrationAuth?.id,
isActive: true,
app: targetApp,
appId: integrationAuthApps?.find((integrationAuthApp) => integrationAuthApp.name === targetApp)?.appId,
appId: integrationAuthApps?.find(
(integrationAuthApp) => integrationAuthApp.name === targetApp
)?.appId,
sourceEnvironment: selectedSourceEnvironment,
targetService: variableType,
secretPath
@@ -90,7 +89,6 @@ export default function TerraformCloudCreateIntegrationPage() {
}
};
return integrationAuth &&
workspace &&
selectedSourceEnvironment &&
@@ -122,23 +120,22 @@ export default function TerraformCloudCreateIntegrationPage() {
placeholder="Provide a path, default is /"
/>
</FormControl>
<FormControl label="Category" className="mt-4" errorText={variableTypeErrorText}
isError={variableTypeErrorText !== "" ?? false}>
<FormControl
label="Category"
className="mt-4"
errorText={variableTypeErrorText}
isError={variableTypeErrorText !== "" ?? false}
>
<Select
value={variableType}
onValueChange={(val) => setVariableType(val)}
className="w-full border border-mineshaft-500"
>
{
variableTypes.map((variable) => (
<SelectItem
value={variable.name}
key={`target-app-${variable.name}`}
>
{variable.name}
</SelectItem>
))
}
{variableTypes.map((variable) => (
<SelectItem value={variable.name} key={`target-app-${variable.name}`}>
{variable.name}
</SelectItem>
))}
</Select>
</FormControl>
<FormControl label="Terraform Cloud Project" className="mt-4">
@@ -1,9 +1,7 @@
import { useState } from "react";
import { useRouter } from "next/router";
import {
useSaveIntegrationAccessToken
} from "@app/hooks/api";
import { useSaveIntegrationAccessToken } from "@app/hooks/api";
import { Button, Card, CardTitle, FormControl, Input } from "../../../components/v2";
@@ -2,9 +2,7 @@ import { useEffect, useState } from "react";
import { useRouter } from "next/router";
import queryString from "query-string";
import {
useCreateIntegration
} from "@app/hooks/api";
import { useCreateIntegration } from "@app/hooks/api";
import {
Button,
@@ -64,7 +62,9 @@ export default function TravisCICreateIntegrationPage() {
integrationAuthId: integrationAuth?.id,
isActive: true,
app: targetApp,
appId: integrationAuthApps?.find((integrationAuthApp) => integrationAuthApp.name === targetApp)?.appId,
appId: integrationAuthApps?.find(
(integrationAuthApp) => integrationAuthApp.name === targetApp
)?.appId,
sourceEnvironment: selectedSourceEnvironment,
secretPath
});
@@ -3,13 +3,16 @@ import Head from "next/head";
import Image from "next/image";
import Link from "next/link";
import { useRouter } from "next/router";
import { faArrowUpRightFromSquare, faBookOpen, faBugs, faCircleInfo } from "@fortawesome/free-solid-svg-icons";
import {
faArrowUpRightFromSquare,
faBookOpen,
faBugs,
faCircleInfo
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import queryString from "query-string";
import {
useCreateIntegration
} from "@app/hooks/api";
import { useCreateIntegration } from "@app/hooks/api";
import {
Button,
@@ -47,9 +50,10 @@ export default function VercelCreateIntegrationPage() {
const { integrationAuthId } = queryString.parse(router.asPath.split("?")[1]);
const { data: workspace } = useGetWorkspaceById(localStorage.getItem("projectData.id") ?? "");
const { data: integrationAuth } = useGetIntegrationAuthById((integrationAuthId as string) ?? "");
const { data: integrationAuthApps, isLoading: isIntegrationAuthAppsLoading } = useGetIntegrationAuthApps({
integrationAuthId: (integrationAuthId as string) ?? ""
});
const { data: integrationAuthApps, isLoading: isIntegrationAuthAppsLoading } =
useGetIntegrationAuthApps({
integrationAuthId: (integrationAuthId as string) ?? ""
});
const { data: branches } = useGetIntegrationAuthVercelBranches({
integrationAuthId: integrationAuthId as string,
@@ -88,7 +92,8 @@ export default function VercelCreateIntegrationPage() {
if (!targetApp || !targetApp.appId) return;
const path = targetEnvironment === "preview" && targetBranch !== "" ? targetBranch : undefined;
const path =
targetEnvironment === "preview" && targetBranch !== "" ? targetBranch : undefined;
await mutateAsync({
integrationAuthId: integrationAuth?.id,
@@ -114,14 +119,14 @@ export default function VercelCreateIntegrationPage() {
integrationAuthApps &&
targetAppId &&
targetEnvironment ? (
<div className="flex flex-col h-full w-full items-center justify-center">
<div className="flex h-full w-full flex-col items-center justify-center">
<Head>
<title>Set Up Vercel Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
<Card className="max-w-lg rounded-md border border-mineshaft-600 p-0">
<CardTitle
className="text-left px-6 text-xl"
<CardTitle
className="px-6 text-left text-xl"
subTitle="Select which environment or folder in Infisical you want to sync to Vercel's environment variables."
>
<div className="flex flex-row items-center">
@@ -136,10 +141,13 @@ export default function VercelCreateIntegrationPage() {
<span className="ml-2">Vercel Integration </span>
<Link href="https://infisical.com/docs/integrations/cloud/vercel" passHref>
<a target="_blank" rel="noopener noreferrer">
<div className="ml-2 mb-1 rounded-md text-yellow text-sm inline-block bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] opacity-80 hover:opacity-100 cursor-default">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5"/>
<div className="ml-2 mb-1 inline-block cursor-default rounded-md bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] text-sm text-yellow opacity-80 hover:opacity-100">
<FontAwesomeIcon icon={faBookOpen} className="mr-1.5" />
Docs
<FontAwesomeIcon icon={faArrowUpRightFromSquare} className="ml-1.5 text-xxs mb-[0.07rem]"/>
<FontAwesomeIcon
icon={faArrowUpRightFromSquare}
className="ml-1.5 mb-[0.07rem] text-xxs"
/>
</div>
</a>
</Link>
@@ -233,31 +241,48 @@ export default function VercelCreateIntegrationPage() {
Create Integration
</Button>
</Card>
<div className="border-t border-mineshaft-800 w-full max-w-md mt-6"/>
<div className="flex flex-col bg-mineshaft-800 border border-mineshaft-600 w-full p-4 max-w-lg mt-6 rounded-md">
<div className="flex flex-row items-center"><FontAwesomeIcon icon={faCircleInfo} className="text-mineshaft-200 text-xl"/> <span className="ml-3 text-md text-mineshaft-100">Pro Tips</span></div>
<span className="text-mineshaft-300 text-sm mt-4">After creating an integration, your secrets will start syncing immediately. This might cause an unexpected override of current secrets in Vercel with secrets from Infisical.</span>
<div className="mt-6 w-full max-w-md border-t border-mineshaft-800" />
<div className="mt-6 flex w-full max-w-lg flex-col rounded-md border border-mineshaft-600 bg-mineshaft-800 p-4">
<div className="flex flex-row items-center">
<FontAwesomeIcon icon={faCircleInfo} className="text-xl text-mineshaft-200" />{" "}
<span className="text-md ml-3 text-mineshaft-100">Pro Tips</span>
</div>
<span className="mt-4 text-sm text-mineshaft-300">
After creating an integration, your secrets will start syncing immediately. This might
cause an unexpected override of current secrets in Vercel with secrets from Infisical.
</span>
</div>
</div>
) : (
<div className="flex justify-center items-center w-full h-full">
<div className="flex h-full w-full items-center justify-center">
<Head>
<title>Set Up Vercel Integration</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
{isIntegrationAuthAppsLoading ? <img src="/images/loading/loading.gif" height={70} width={120} alt="infisical loading indicator" /> : <div className="max-w-md h-max p-6 border border-mineshaft-600 rounded-md bg-mineshaft-800 text-mineshaft-200 flex flex-col text-center">
<FontAwesomeIcon icon={faBugs} className="text-6xl my-2 inlineli"/>
<p>
Something went wrong. Please contact <a
className="inline underline underline-offset-4 decoration-primary-500 opacity-80 hover:opacity-100 text-mineshaft-100 duration-200 cursor-pointer"
target="_blank"
rel="noopener noreferrer"
href="mailto:[email protected]"
>
support@infisical.com
</a> if the issue persists.
</p>
</div>}
{isIntegrationAuthAppsLoading ? (
<img
src="/images/loading/loading.gif"
height={70}
width={120}
alt="infisical loading indicator"
/>
) : (
<div className="flex h-max max-w-md flex-col rounded-md border border-mineshaft-600 bg-mineshaft-800 p-6 text-center text-mineshaft-200">
<FontAwesomeIcon icon={faBugs} className="inlineli my-2 text-6xl" />
<p>
Something went wrong. Please contact{" "}
<a
className="inline cursor-pointer text-mineshaft-100 underline decoration-primary-500 underline-offset-4 opacity-80 duration-200 hover:opacity-100"
target="_blank"
rel="noopener noreferrer"
href="mailto:[email protected]"
>
support@infisical.com
</a>{" "}
if the issue persists.
</p>
</div>
)}
</div>
);
}
@@ -2,9 +2,7 @@ import { useEffect } from "react";
import { useRouter } from "next/router";
import queryString from "query-string";
import {
useAuthorizeIntegration
} from "@app/hooks/api";
import { useAuthorizeIntegration } from "@app/hooks/api";
export default function VercelOAuth2CallbackPage() {
const router = useRouter();
@@ -18,7 +16,7 @@ export default function VercelOAuth2CallbackPage() {
// validate state
if (state !== localStorage.getItem("latestCSRFToken")) return;
localStorage.removeItem("latestCSRFToken");
const integrationAuth = await mutateAsync({
workspaceId: localStorage.getItem("projectData.id") as string,
code: code as string,
@@ -1,13 +1,10 @@
import { useState } from "react";
import { useRouter } from "next/router";
import {
useSaveIntegrationAccessToken
} from "@app/hooks/api";
import { useSaveIntegrationAccessToken } from "@app/hooks/api";
import { Button, Card, CardTitle, FormControl, Input } from "../../../components/v2";
export default function WindmillCreateIntegrationPage() {
const router = useRouter();
const { mutateAsync } = useSaveIntegrationAccessToken();
@@ -15,7 +12,7 @@ export default function WindmillCreateIntegrationPage() {
const [apiKey, setApiKey] = useState("");
const [apiKeyErrorText, setApiKeyErrorText] = useState("");
const [isLoading, setIsLoading] = useState(false);
const handleButtonClick = async () => {
try {
setApiKeyErrorText("");
@@ -23,17 +20,17 @@ export default function WindmillCreateIntegrationPage() {
setApiKeyErrorText("API Key cannot be blank");
return;
}
setIsLoading(true);
const integrationAuth = await mutateAsync({
workspaceId: localStorage.getItem("projectData.id"),
integration: "windmill",
accessToken: apiKey
});
setIsLoading(false);
router.push(`/integrations/windmill/create?integrationAuthId=${integrationAuth.id}`);
} catch (err) {
console.error(err);
@@ -41,27 +38,27 @@ export default function WindmillCreateIntegrationPage() {
};
return (
<div className="flex h-full w-full items-center justify-center">
<Card className="max-w-md rounded-md p-8">
<CardTitle className="text-center">Windmill Integration</CardTitle>
<FormControl
label="Windmill Access Token"
errorText={apiKeyErrorText}
isError={apiKeyErrorText !== "" ?? false}
>
<Input placeholder="" value={apiKey} onChange={(e) => setApiKey(e.target.value)} />
</FormControl>
<Button
onClick={handleButtonClick}
color="mineshaft"
className="mt-4"
isLoading={isLoading}
>
Connect to Windmill
</Button>
</Card>
</div>
);
<div className="flex h-full w-full items-center justify-center">
<Card className="max-w-md rounded-md p-8">
<CardTitle className="text-center">Windmill Integration</CardTitle>
<FormControl
label="Windmill Access Token"
errorText={apiKeyErrorText}
isError={apiKeyErrorText !== "" ?? false}
>
<Input placeholder="" value={apiKey} onChange={(e) => setApiKey(e.target.value)} />
</FormControl>
<Button
onClick={handleButtonClick}
color="mineshaft"
className="mt-4"
isLoading={isLoading}
>
Connect to Windmill
</Button>
</Card>
</div>
);
}
WindmillCreateIntegrationPage.requireAuth = true;
WindmillCreateIntegrationPage.requireAuth = true;
@@ -2,9 +2,7 @@ import { useEffect, useState } from "react";
import { useRouter } from "next/router";
import queryString from "query-string";
import {
useCreateIntegration
} from "@app/hooks/api";
import { useCreateIntegration } from "@app/hooks/api";
import {
Button,
@@ -65,7 +63,9 @@ export default function WindmillCreateIntegrationPage() {
integrationAuthId: integrationAuth?.id,
isActive: true,
app: targetApp,
appId: integrationAuthApps?.find((integrationAuthApp) => integrationAuthApp.name === targetApp)?.appId,
appId: integrationAuthApps?.find(
(integrationAuthApp) => integrationAuthApp.name === targetApp
)?.appId,
sourceEnvironment: selectedSourceEnvironment,
secretPath
});