Begin personal access token-based integrations

This commit is contained in:
Tuan Dang
2022-12-16 15:44:50 -05:00
parent 6c7d232a9e
commit 36300cd19d
3 changed files with 143 additions and 11 deletions
@@ -0,0 +1,100 @@
import { Fragment } from "react";
import { Dialog, Transition } from "@headlessui/react";
import getLatestFileKey from "../../../pages/api/workspace/getLatestFileKey";
import setBotActiveStatus from "../../../pages/api/bot/setBotActiveStatus";
import {
decryptAssymmetric,
encryptAssymmetric
} from "../../utilities/cryptography/crypto";
import Button from "../buttons/Button";
import InputField from "../InputField";
const IntegrationAccessTokenDialog = ({
isOpen,
closeModal,
selectedIntegrationOption,
handleBotActivate,
handleIntegrationOption
}) => {
const submit = async () => {
try {
// 1. activate bot
await handleBotActivate();
// 2. start integration
await handleIntegrationOption({
integrationOption: selectedIntegrationOption
});
} catch (err) {
console.log(err);
}
closeModal();
}
return (
<div>
<Transition appear show={isOpen} as={Fragment}>
<Dialog as="div" className="relative z-10" onClose={closeModal}>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-black bg-opacity-70" />
</Transition.Child>
<div className="fixed inset-0 overflow-y-auto">
<div className="flex min-h-full items-center justify-center p-4 text-center">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 scale-95"
enterTo="opacity-100 scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
<Dialog.Panel className="w-full max-w-md transform overflow-hidden rounded-md bg-bunker-800 border border-gray-700 p-6 text-left align-middle shadow-xl transition-all">
<Dialog.Title
as="h3"
className="text-lg font-medium leading-6 text-gray-400"
>
Grant Infisical access to your secrets
</Dialog.Title>
<div className="mt-2 mb-2">
<p className="text-sm text-gray-500">
Most cloud integrations require Infisical to be able to decrypt your secrets so they can be forwarded over.
</p>
</div>
<div className="mt-6 max-w-max">
{/* <Button
onButtonPressed={submit}
color="mineshaft"
text="Grant access"
size="md"
/> */}
<InputField
label="Access token"
onChangeHandler={() => {}}
type="varName"
value={"Hello"}
placeholder=""
isRequired
/>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition>
</div>
);
}
export default IntegrationAccessTokenDialog;
+18 -3
View File
@@ -15,6 +15,7 @@ import getBot from "../api/bot/getBot";
import setBotActiveStatus from "../api/bot/setBotActiveStatus"; import setBotActiveStatus from "../api/bot/setBotActiveStatus";
import getLatestFileKey from "../api/workspace/getLatestFileKey"; import getLatestFileKey from "../api/workspace/getLatestFileKey";
import ActivateBotDialog from "~/components/basic/dialog/ActivateBotDialog"; import ActivateBotDialog from "~/components/basic/dialog/ActivateBotDialog";
import IntegrationAccessTokenDialog from "~/components/basic/dialog/IntegrationAccessTokenDialog";
const { const {
decryptAssymmetric, decryptAssymmetric,
encryptAssymmetric encryptAssymmetric
@@ -27,7 +28,8 @@ export default function Integrations() {
const [integrationAuths, setIntegrationAuths] = useState([]); const [integrationAuths, setIntegrationAuths] = useState([]);
const [integrations, setIntegrations] = useState([]); const [integrations, setIntegrations] = useState([]);
const [bot, setBot] = useState(null); const [bot, setBot] = useState(null);
const [isActivateBotOpen, setIsActivateBotOpen] = useState(false); const [isActivateBotDialogOpen, setIsActivateBotDialogOpen] = useState(false);
const [isIntegrationAccessTokenDialogOpen, setIntegrationAccessTokenDialogOpen] = useState(true);
const [selectedIntegrationOption, setSelectedIntegrationOption] = useState(null); const [selectedIntegrationOption, setSelectedIntegrationOption] = useState(null);
const router = useRouter(); const router = useRouter();
@@ -120,6 +122,8 @@ export default function Integrations() {
const state = crypto.randomBytes(16).toString("hex"); const state = crypto.randomBytes(16).toString("hex");
localStorage.setItem('latestCSRFToken', state); localStorage.setItem('latestCSRFToken', state);
// TODO: Add CircleCI, Render, Fly.io
switch (integrationOption.name) { switch (integrationOption.name) {
case 'Heroku': case 'Heroku':
window.location = `https://id.heroku.com/oauth/authorize?client_id=${integrationOption.clientId}&response_type=code&scope=write-protected&state=${state}`; window.location = `https://id.heroku.com/oauth/authorize?client_id=${integrationOption.clientId}&response_type=code&scope=write-protected&state=${state}`;
@@ -130,6 +134,10 @@ export default function Integrations() {
case 'Netlify': case 'Netlify':
window.location = `https://app.netlify.com/authorize?client_id=${integrationOption.clientId}&response_type=code&redirect_uri=${integrationOption.redirectURL}&state=${state}`; window.location = `https://app.netlify.com/authorize?client_id=${integrationOption.clientId}&response_type=code&redirect_uri=${integrationOption.redirectURL}&state=${state}`;
break; break;
case 'Fly.io':
console.log('fly.io');
setIntegrationAccessTokenDialogOpen(true);
break;
} }
} catch (err) { } catch (err) {
console.log(err); console.log(err);
@@ -179,8 +187,15 @@ export default function Integrations() {
isProjectRelated={true} isProjectRelated={true}
/> />
<ActivateBotDialog <ActivateBotDialog
isOpen={isActivateBotOpen} isOpen={isActivateBotDialogOpen}
closeModal={() => setIsActivateBotOpen(false)} closeModal={() => setIsActivateBotDialogOpen(false)}
selectedIntegrationOption={selectedIntegrationOption}
handleBotActivate={handleBotActivate}
handleIntegrationOption={handleIntegrationOption}
/>
<IntegrationAccessTokenDialog
isOpen={isIntegrationAccessTokenDialogOpen}
closeModal={() => setIntegrationAccessTokenDialogOpen(false)}
selectedIntegrationOption={selectedIntegrationOption} selectedIntegrationOption={selectedIntegrationOption}
handleBotActivate={handleBotActivate} handleBotActivate={handleBotActivate}
handleIntegrationOption={handleIntegrationOption} handleIntegrationOption={handleIntegrationOption}
+25 -8
View File
@@ -5,7 +5,8 @@
"image": "Heroku", "image": "Heroku",
"isAvailable": true, "isAvailable": true,
"type": "oauth2", "type": "oauth2",
"clientId": "7b1311a1-1cb2-4938-8adf-f37a399ec41b" "clientId": "7b1311a1-1cb2-4938-8adf-f37a399ec41b",
"docsLink": ""
}, },
{ {
"name": "Vercel", "name": "Vercel",
@@ -13,7 +14,8 @@
"image": "Vercel", "image": "Vercel",
"isAvailable": true, "isAvailable": true,
"type": "vercel", "type": "vercel",
"clientId": "" "clientId": "",
"docsLink": ""
}, },
{ {
"name": "Netlify", "name": "Netlify",
@@ -22,7 +24,17 @@
"isAvailable": true, "isAvailable": true,
"type": "oauth2", "type": "oauth2",
"clientId": "fYWBhD3gt0pT62UIwYrlGRcy--pPVLYIQad6ORrES9o", "clientId": "fYWBhD3gt0pT62UIwYrlGRcy--pPVLYIQad6ORrES9o",
"redirectURL": "http://localhost:8080/netlify" "redirectURL": "http://localhost:8080/netlify",
"docsLink": ""
},
{
"name": "Fly.io",
"slug": "flyio",
"image": "Google Cloud Platform",
"isAvailable": true,
"type": "accessToken",
"clientId": "",
"docsLink": ""
}, },
{ {
"name": "Google Cloud Platform", "name": "Google Cloud Platform",
@@ -30,7 +42,8 @@
"image": "Google Cloud Platform", "image": "Google Cloud Platform",
"isAvailable": false, "isAvailable": false,
"type": "", "type": "",
"clientId": "" "clientId": "",
"docsLink": ""
}, },
{ {
"name": "Amazon Web Services", "name": "Amazon Web Services",
@@ -38,7 +51,8 @@
"image": "Amazon Web Services", "image": "Amazon Web Services",
"isAvailable": false, "isAvailable": false,
"type": "", "type": "",
"clientId": "" "clientId": "",
"docsLink": ""
}, },
{ {
"name": "Microsoft Azure", "name": "Microsoft Azure",
@@ -46,7 +60,8 @@
"image": "Microsoft Azure", "image": "Microsoft Azure",
"isAvailable": false, "isAvailable": false,
"type": "", "type": "",
"clientId": "" "clientId": "",
"docsLink": ""
}, },
{ {
"name": "Travis CI", "name": "Travis CI",
@@ -54,7 +69,8 @@
"image": "Travis CI", "image": "Travis CI",
"isAvailable": false, "isAvailable": false,
"type": "", "type": "",
"clientId": "" "clientId": "",
"docsLink": ""
}, },
{ {
"name": "Circle CI", "name": "Circle CI",
@@ -62,6 +78,7 @@
"image": "Circle CI", "image": "Circle CI",
"isAvailable": false, "isAvailable": false,
"type": "", "type": "",
"clientId": "" "clientId": "",
"docsLink": ""
} }
] ]