Merge branch 'bot' into bot

This commit is contained in:
BlackMagiq
2022-12-21 17:11:09 -05:00
committed by GitHub
85 changed files with 2107 additions and 790 deletions
+1 -1
View File
@@ -10,7 +10,7 @@ WORKDIR /app
COPY package.json package-lock.json next.config.js ./
# Install dependencies
RUN npm ci --only-production
RUN npm ci --only-production --ignore-scripts
# Rebuild the source code only when needed
+2 -2
View File
@@ -9,7 +9,7 @@ COPY package.json ./
COPY package-lock.json ./
# Install
RUN npm install
RUN npm install --ignore-scripts
# Copy over next.js config
COPY next.config.js ./next.config.js
@@ -17,4 +17,4 @@ COPY next.config.js ./next.config.js
# Copy all files
COPY . .
CMD ["npm", "run", "dev"]
CMD ["npm", "run", "dev"]
-20
View File
@@ -1,20 +0,0 @@
# Base layer
FROM node:16-alpine
# Set the working directory
WORKDIR /app
# Copy over dependency files
COPY package.json ./
COPY package-lock.json ./
# Install
RUN npm install
# Copy over next.js config
COPY next.config.js ./next.config.js
# Copy all files
COPY . .
CMD ["npm", "run", "start:docker"]
+4 -4
View File
@@ -10,10 +10,10 @@ import { Listbox, Transition } from "@headlessui/react";
interface ListBoxProps {
selected: string;
onChange: () => void;
data: string[];
text: string;
buttonAction: () => void;
onChange: (arg: string) => void;
data: string[] | null;
text?: string;
buttonAction?: () => void;
isFull?: boolean;
}
+1 -1
View File
@@ -9,7 +9,7 @@ import {
const classNames = require("classnames");
type ButtonProps = {
text: string;
text?: string;
onButtonPressed: () => void;
loading?: boolean;
color?: string;
@@ -1,30 +1,32 @@
import React from "react";
import Image from "next/image";
import { useRouter } from "next/router";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
faCheck,
faX,
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import deleteIntegrationAuth from "../../pages/api/integrations/DeleteIntegrationAuth";
interface CloudIntegrationOption {
isAvailable: Boolean;
isAvailable: boolean;
name: string;
type: string;
clientId: string;
docsLink: string;
slug: string;
}
interface IntegrationAuth {
id: string;
_id: string;
integration: string;
}
interface Props {
cloudIntegrationOption: CloudIntegrationOption;
setSelectedIntegrationOption: () => void;
integrationOptionPress: () => void;
setSelectedIntegrationOption: (cloudIntegration: CloudIntegrationOption) => void;
integrationOptionPress: (cloudIntegrationOption: CloudIntegrationOption) => void;
integrationAuths: IntegrationAuth[];
}
@@ -45,9 +47,7 @@ const CloudIntegration = ({
onClick={() => {
if (!cloudIntegrationOption.isAvailable) return;
setSelectedIntegrationOption(cloudIntegrationOption);
integrationOptionPress({
integrationOption: cloudIntegrationOption
});
integrationOptionPress(cloudIntegrationOption);
}}
key={cloudIntegrationOption.name}
>
@@ -1,11 +1,14 @@
import React from "react";
import CloudIntegration from "./CloudIntegration";
interface CloudIntegrationOption {
isAvailable: boolean;
name: string;
type: string;
clientId: string;
docsLink: string;
slug: string;
}
interface Props {
@@ -1,14 +1,17 @@
import React from "react";
import FrameworkIntegration from "./FrameworkIntegration";
interface Framework {
name: string;
image: string;
link: string;
slug: string;
docsLink: string;
}
interface Props {
framework: Framework
frameworks: [Framework]
}
const FrameworkIntegrationSection = ({ frameworks }: Props) => {
@@ -6,23 +6,33 @@ import {
faX,
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
envMapping,
reverseEnvMapping,
reverseContextNetlifyMapping
} from "../../public/data/frequentConstants";
import updateIntegration from "../../pages/api/integrations/updateIntegration"
import deleteIntegration from "../../pages/api/integrations/DeleteIntegration"
import getIntegrationApps from "../../pages/api/integrations/GetIntegrationApps";
import Button from "~/components/basic/buttons/Button";
import ListBox from "~/components/basic/Listbox";
import deleteIntegration from "../../pages/api/integrations/DeleteIntegration"
import getIntegrationApps from "../../pages/api/integrations/GetIntegrationApps";
import updateIntegration from "../../pages/api/integrations/updateIntegration"
import {
contextNetlifyMapping,
envMapping,
reverseContextNetlifyMapping,
reverseEnvMapping,
} from "../../public/data/frequentConstants";
interface Integration {
_id: string;
app?: string;
environment: string;
integration: string;
integrationAuth: string;
isActive: Boolean;
isActive: boolean;
context: string;
}
interface IntegrationApp {
name: string;
siteId: string;
}
const Integration = ({
@@ -35,39 +45,44 @@ const Integration = ({
);
const [fileState, setFileState] = useState([]);
const router = useRouter();
const [apps, setApps] = useState([]); // integration app objects
const [integrationApp, setIntegrationApp] = useState(null); // integration app name
const [integrationTarget, setIntegrationTarget] = useState(null); // vercel-specific integration param
const [integrationContext, setIntegrationContext] = useState(null); // netlify-specific integration param
const [apps, setApps] = useState<IntegrationApp[]>([]); // integration app objects
const [integrationApp, setIntegrationApp] = useState(""); // integration app name
const [integrationTarget, setIntegrationTarget] = useState(""); // vercel-specific integration param
const [integrationContext, setIntegrationContext] = useState(""); // netlify-specific integration param
useEffect(async () => {
interface App {
name: string;
siteId?: string;
}
useEffect(() => {
const tempApps = await getIntegrationApps({
integrationAuthId: integration.integrationAuth,
});
setApps(tempApps);
setIntegrationApp(
integration.app ? integration.app : tempApps[0].name
);
switch (integration.integration) {
case "vercel":
setIntegrationTarget("Development");
break;
case "netlify":
setIntegrationContext("All");
break;
default:
break;
const loadIntegration = async () => {
interface App {
name: string;
siteId?: string;
}
const tempApps: [IntegrationApp] = await getIntegrationApps({
integrationAuthId: integration.integrationAuth,
});
setApps(tempApps);
setIntegrationApp(
integration.app ? integration.app : tempApps[0].name
);
switch (integration.integration) {
case "vercel":
setIntegrationTarget("Development");
break;
case "netlify":
setIntegrationContext(integration?.context ? contextNetlifyMapping[integration.context] : "Local development");
break;
default:
break;
}
}
loadIntegration();
}, []);
const renderIntegrationSpecificParams = (integration) => {
const renderIntegrationSpecificParams = (integration: Integration) => {
try {
switch (integration.integration) {
case "vercel":
@@ -77,11 +92,11 @@ const Integration = ({
ENVIRONMENT
</div>
<ListBox
data={!integration.isActive && [
data={!integration.isActive ? [
"Production",
"Preview",
"Development"
]}
] : null}
selected={"Production"}
onChange={setIntegrationTarget}
/>
@@ -94,13 +109,12 @@ const Integration = ({
CONTEXT
</div>
<ListBox
data={!integration.isActive && [
"All",
data={!integration.isActive ? [
"Production",
"Deploy previews",
"Branch deploys",
"Local development"
]}
] : null}
selected={integrationContext}
onChange={setIntegrationContext}
/>
@@ -128,7 +142,9 @@ const Integration = ({
"Production",
] : null}
selected={integrationEnvironment}
onChange={setIntegrationEnvironment}
onChange={(environment) => {
setIntegrationEnvironment(environment);
}}
isFull={true}
/>
</div>
@@ -152,9 +168,11 @@ const Integration = ({
APP
</div>
<ListBox
data={!integration.isActive && apps.map((app) => app.name)}
data={!integration.isActive ? apps.map((app) => app.name) : null}
selected={integrationApp}
onChange={setIntegrationApp}
onChange={(app) => {
setIntegrationApp(app);
}}
/>
</div>
{renderIntegrationSpecificParams(integration)}
@@ -172,7 +190,10 @@ const Integration = ({
<Button
text="Start Integration"
onButtonPressed={async () => {
const siteId = apps.find((app) => app.name === integrationApp).siteId ? apps.find((app) => app.name === integrationApp).siteId : null;
const siteApp = apps.find((app) => app.name === integrationApp); // obj or undefined
const siteId = siteApp?.siteId ? siteApp.siteId : null;
const result = await updateIntegration({
integrationId: integration._id,
environment: envMapping[integrationEnvironment],
@@ -182,6 +203,7 @@ const Integration = ({
context: integrationContext ? reverseContextNetlifyMapping[integrationContext] : null,
siteId
});
router.reload();
}}
color="mineshaft"
@@ -1,15 +1,23 @@
import React from "react";
import Integration from "./Integration";
import guidGenerator from "~/utilities/randomId";
interface Integration {
}
import Integration from "./Integration";
interface Props {
integrations: any
}
interface IntegrationType {
_id: string;
app?: string;
environment: string;
integration: string;
integrationAuth: string;
isActive: boolean;
context: string;
}
const ProjectIntegrationSection = ({
integrations
}: Props) => {
@@ -21,12 +29,12 @@ const ProjectIntegrationSection = ({
Manage your integrations of Infisical with third-party services.
</p>
</div>
{integrations.map((integration => (
{integrations.map((integration: IntegrationType) => (
<Integration
key={guidGenerator()}
integration={integration}
/>
)))}
))}
</div>
) : <div></div>
}
@@ -42,9 +42,9 @@ const attemptLogin = async (
async () => {
const clientPublicKey = client.getPublicKey();
const { serverPublicKey, salt } = await login1(email, clientPublicKey);
try {
const { serverPublicKey, salt } = await login1(email, clientPublicKey);
client.setSalt(salt);
client.setServerPublicKey(serverPublicKey);
const clientProof = client.getProof(); // called M1
@@ -4,15 +4,11 @@ const POSTHOG_HOST =
process.env.NEXT_PUBLIC_POSTHOG_HOST! || "https://app.posthog.com";
const STRIPE_PRODUCT_PRO = process.env.NEXT_PUBLIC_STRIPE_PRODUCT_PRO!;
const STRIPE_PRODUCT_STARTER = process.env.NEXT_PUBLIC_STRIPE_PRODUCT_STARTER!;
const CLIENT_ID_HEROKU = process.env.NEXT_PUBLIC_CLIENT_ID_HEROKU!;
const CLIENT_ID_NETLIFY = process.env.NEXT_PUBLIC_CLIENT_ID_NETLIFY!;
export {
ENV,
POSTHOG_API_KEY,
POSTHOG_HOST,
STRIPE_PRODUCT_PRO,
STRIPE_PRODUCT_STARTER,
CLIENT_ID_HEROKU,
CLIENT_ID_NETLIFY
STRIPE_PRODUCT_STARTER
};
-22
View File
@@ -60,7 +60,6 @@
"eslint-import-resolver-typescript": "^3.5.2",
"eslint-plugin-simple-import-sort": "^8.0.0",
"postcss": "^8.4.14",
"prettier": "2.7.1",
"tailwindcss": "^3.1.4",
"typescript": "^4.9.3"
}
@@ -5999,21 +5998,6 @@
"node": ">= 0.8.0"
}
},
"node_modules/prettier": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
"integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
"dev": true,
"bin": {
"prettier": "bin-prettier.js"
},
"engines": {
"node": ">=10.13.0"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
@@ -11950,12 +11934,6 @@
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
"dev": true
},
"prettier": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
"integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
"dev": true
},
"process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+1 -1
View File
@@ -1,6 +1,7 @@
{
"private": true,
"scripts": {
"prepare": "cd .. && npm install",
"dev": "next dev",
"build": "next build",
"start": "next start",
@@ -63,7 +64,6 @@
"eslint-import-resolver-typescript": "^3.5.2",
"eslint-plugin-simple-import-sort": "^8.0.0",
"postcss": "^8.4.14",
"prettier": "2.7.1",
"tailwindcss": "^3.1.4",
"typescript": "^4.9.3"
}
+1 -1
View File
@@ -7,7 +7,7 @@ interface BotKey {
interface Props {
botId: string;
isActive: Boolean;
isActive: boolean;
botKey: BotKey;
}
@@ -22,6 +22,15 @@ const updateIntegration = ({
target,
context,
siteId
}: {
integrationId: string,
app: string,
environment: string,
isActive: boolean,
target: string | null,
context: string | null,
siteId: string | null
}) => {
return SecurityClient.fetchCall(
"/api/v1/integration/" + integrationId,
@@ -40,7 +49,7 @@ const updateIntegration = ({
}),
}
).then(async (res) => {
if (res.status == 200) {
if (res && res.status == 200) {
return res;
} else {
console.log("Failed to start an integration");
+21 -20
View File
@@ -2,20 +2,22 @@ import React, { useEffect, useState } from "react";
import Head from "next/head";
import Image from "next/image";
import { useRouter } from "next/router";
import NavHeader from "~/components/navigation/NavHeader";
import Integration from "~/components/integrations/Integration";
import FrameworkIntegrationSection from "~/components/integrations/FrameworkIntegrationSection";
import CloudIntegrationSection from "~/components/integrations/CloudIntegrationSection";
import IntegrationSection from "~/components/integrations/IntegrationSection";
import frameworkIntegrationOptions from "../../public/json/frameworkIntegrations.json";
import getWorkspaceAuthorizations from "../api/integrations/getWorkspaceAuthorizations";
import getWorkspaceIntegrations from "../api/integrations/getWorkspaceIntegrations";
import getIntegrationOptions from "../api/integrations/GetIntegrationOptions";
import getBot from "../api/bot/getBot";
import setBotActiveStatus from "../api/bot/setBotActiveStatus";
import getLatestFileKey from "../api/workspace/getLatestFileKey";
import ActivateBotDialog from "~/components/basic/dialog/ActivateBotDialog";
import IntegrationAccessTokenDialog from "~/components/basic/dialog/IntegrationAccessTokenDialog";
import CloudIntegrationSection from "~/components/integrations/CloudIntegrationSection";
import FrameworkIntegrationSection from "~/components/integrations/FrameworkIntegrationSection";
import Integration from "~/components/integrations/Integration";
import IntegrationSection from "~/components/integrations/IntegrationSection";
import NavHeader from "~/components/navigation/NavHeader";
import frameworkIntegrationOptions from "../../public/json/frameworkIntegrations.json";
import getBot from "../api/bot/getBot";
import setBotActiveStatus from "../api/bot/setBotActiveStatus";
import getIntegrationOptions from "../api/integrations/GetIntegrationOptions";
import getWorkspaceAuthorizations from "../api/integrations/getWorkspaceAuthorizations";
import getWorkspaceIntegrations from "../api/integrations/getWorkspaceIntegrations";
import getLatestFileKey from "../api/workspace/getLatestFileKey";
const {
decryptAssymmetric,
encryptAssymmetric
@@ -39,7 +41,7 @@ export default function Integrations() {
setCloudIntegrationOptions(
await getIntegrationOptions()
);
// get project integration authorizations
setIntegrationAuths(
await getWorkspaceAuthorizations({
@@ -132,7 +134,7 @@ export default function Integrations() {
window.location = `https://id.heroku.com/oauth/authorize?client_id=${integrationOption.clientId}&response_type=code&scope=write-protected&state=${state}`;
break;
case 'Vercel':
window.location = `https://vercel.com/integrations/infisical-dev/new?state=${state}`;
window.location = `https://vercel.com/integrations/${integrationOption.clientSlug}/new?state=${state}`;
break;
case 'Netlify':
window.location = `https://app.netlify.com/authorize?client_id=${integrationOption.clientId}&response_type=code&redirect_uri=${integrationOption.redirectURL}&state=${state}`;
@@ -158,14 +160,13 @@ export default function Integrations() {
/**
* Open dialog to activate bot if bot is not active.
* Otherwise, start integration [integrationOption]
* @param {Object} obj
* @param {Object} obj.integrationOption - an integration option
* @param {String} obj.name
* @param {String} obj.type
* @param {String} obj.docsLink
* @param {Object} integrationOption - an integration option
* @param {String} integrationOption.name
* @param {String} integrationOption.type
* @param {String} integrationOption.docsLink
* @returns
*/
const integrationOptionPress = ({ integrationOption }) => {
const integrationOptionPress = (integrationOption) => {
try {
if (bot.isActive) {
// case: bot is active -> proceed with integration
+11 -13
View File
@@ -16,20 +16,18 @@ export default function Netlify() {
*/
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(async () => {
if (state === localStorage.getItem('latestCSRFToken')) {
localStorage.removeItem('latestCSRFToken');
await AuthorizeIntegration({
workspaceId: localStorage.getItem('projectData.id'),
code,
integration: "netlify"
});
router.push("/integrations/" + localStorage.getItem("projectData.id"));
}
try {
if (state === localStorage.getItem('latestCSRFToken')) {
localStorage.removeItem('latestCSRFToken');
await AuthorizeIntegration({
workspaceId: localStorage.getItem('projectData.id'),
code,
integration: "netlify"
});
router.push("/integrations/" + localStorage.getItem("projectData.id"));
}
} catch (err) {
console.error('Netlify integration error: ', err);
}
+11 -13
View File
@@ -15,20 +15,18 @@ export default function Vercel() {
*/
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(async () => {
if (state === localStorage.getItem('latestCSRFToken')) {
localStorage.removeItem('latestCSRFToken');
await AuthorizeIntegration({
workspaceId: localStorage.getItem('projectData.id'),
code,
integration: "vercel"
});
router.push("/integrations/" + localStorage.getItem("projectData.id"));
}
try {
if (state === localStorage.getItem('latestCSRFToken')) {
localStorage.removeItem('latestCSRFToken');
await AuthorizeIntegration({
workspaceId: localStorage.getItem('projectData.id'),
code,
integration: "vercel"
});
router.push("/integrations/" + localStorage.getItem("projectData.id"));
}
} catch (err) {
console.error('Vercel integration error: ', err);
}
+16 -10
View File
@@ -1,23 +1,29 @@
const envMapping = {
interface Mapping {
[key: string]: string;
}
const envMapping: Mapping = {
Development: "dev",
Staging: "staging",
Production: "prod",
Testing: "test",
};
const reverseEnvMapping = {
const reverseEnvMapping: Mapping = {
dev: "Development",
staging: "Staging",
prod: "Production",
test: "Testing",
};
const vercelMapping = {
const contextNetlifyMapping: Mapping = {
"dev": "Local development",
"branch-deploy": "Branch deploys",
"deploy-review": "Deploy Previews",
"production": "Production"
}
const reverseContextNetlifyMapping = {
"All": "all",
const reverseContextNetlifyMapping: Mapping = {
"Local development": "dev",
"Branch deploys": "branch-deploy",
"Deploy Previews": "deploy-preview",
@@ -25,7 +31,7 @@ const reverseContextNetlifyMapping = {
}
export {
contextNetlifyMapping,
envMapping,
reverseEnvMapping,
reverseContextNetlifyMapping
};
reverseContextNetlifyMapping,
reverseEnvMapping}