mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-09 18:28:27 +00:00
Begin refactoring all integrations to separate integration pages by step
This commit is contained in:
@@ -3,6 +3,7 @@ export {
|
||||
useDeleteWorkspace,
|
||||
useDeleteWsEnvironment,
|
||||
useGetUserWorkspaces,
|
||||
useGetWorkspaceById,
|
||||
useRenameWorkspace,
|
||||
useUpdateWsEnvironment
|
||||
} from './queries';
|
||||
|
||||
@@ -11,16 +11,30 @@ import {
|
||||
Workspace
|
||||
} from './types';
|
||||
|
||||
|
||||
const workspaceKeys = {
|
||||
getWorkspaceById: (workspaceId: string) => [{ workspaceId }, 'workspace'] as const,
|
||||
getAllUserWorkspace: ['workspaces'] as const
|
||||
};
|
||||
|
||||
const fetchWorkspaceById = async (workspaceId: string) => {
|
||||
const { data } = await apiRequest.get<{ workspace: Workspace }>(`/api/v1/workspace/${workspaceId}`);
|
||||
return data.workspace;
|
||||
}
|
||||
|
||||
const fetchUserWorkspaces = async () => {
|
||||
const { data } = await apiRequest.get<{ workspaces: Workspace[] }>('/api/v1/workspace');
|
||||
|
||||
return data.workspaces;
|
||||
};
|
||||
|
||||
export const useGetWorkspaceById = (workspaceId: string) => {
|
||||
return useQuery({
|
||||
queryKey: workspaceKeys.getWorkspaceById(workspaceId),
|
||||
queryFn: () => fetchWorkspaceById(workspaceId),
|
||||
enabled: true
|
||||
});
|
||||
};
|
||||
|
||||
export const useGetUserWorkspaces = () =>
|
||||
useQuery(workspaceKeys.getAllUserWorkspace, fetchUserWorkspaces);
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ const AuthorizeIntegration = ({ workspaceId, code, integration }: Props) =>
|
||||
})
|
||||
}).then(async (res) => {
|
||||
if (res && res.status === 200) {
|
||||
return (res.json());
|
||||
return (await res.json()).integrationAuth;
|
||||
}
|
||||
console.log('Failed to authorize the integration');
|
||||
return undefined;
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import SecurityClient from '@app/components/utilities/SecurityClient';
|
||||
|
||||
interface Props {
|
||||
integrationAuthId: string;
|
||||
integrationAuthId: string;
|
||||
isActive: boolean;
|
||||
app: string | null;
|
||||
}
|
||||
/**
|
||||
* This route creates a new integration based on the integration authorization with id [integrationAuthId]
|
||||
@@ -10,7 +12,9 @@ interface Props {
|
||||
* @returns
|
||||
*/
|
||||
const createIntegration = ({
|
||||
integrationAuthId
|
||||
integrationAuthId,
|
||||
isActive,
|
||||
app
|
||||
}: Props) =>
|
||||
SecurityClient.fetchCall('/api/v1/integration', {
|
||||
method: 'POST',
|
||||
@@ -18,7 +22,9 @@ const createIntegration = ({
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
integrationAuthId
|
||||
integrationAuthId,
|
||||
isActive,
|
||||
app
|
||||
})
|
||||
}).then(async (res) => {
|
||||
if (res && res.status === 200) {
|
||||
|
||||
@@ -13,71 +13,54 @@ import {
|
||||
Select,
|
||||
SelectItem
|
||||
} from '../components/v2';
|
||||
import { useGetWorkspaceById } from '../hooks/api/workspace';
|
||||
import AuthorizeIntegration from './api/integrations/authorizeIntegration';
|
||||
import updateIntegration from './api/integrations/updateIntegration';
|
||||
import getAWorkspace from './api/workspace/getAWorkspace';
|
||||
import createIntegration from './api/integrations/createIntegration';
|
||||
|
||||
interface Integration {
|
||||
interface IntegrationAuth {
|
||||
_id: string;
|
||||
isActive: boolean;
|
||||
app: string | null;
|
||||
appId: string | null;
|
||||
integration: string;
|
||||
workspace: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
environment: string;
|
||||
integration: string;
|
||||
targetEnvironment: string;
|
||||
workspace: string;
|
||||
integrationAuth: string;
|
||||
}
|
||||
|
||||
export default function AzureKeyVault() {
|
||||
const router = useRouter();
|
||||
const workspaceResult = useGetWorkspaceById(localStorage.getItem('projectData.id') ?? '');
|
||||
|
||||
// query-string variables
|
||||
const parsedUrl = queryString.parse(router.asPath.split('?')[1]);
|
||||
const {code} = parsedUrl;
|
||||
const {state} = parsedUrl;
|
||||
const { code, state } = queryString.parse(router.asPath.split('?')[1]);
|
||||
|
||||
const [integrationAuth, setIntegrationAuth] = useState<IntegrationAuth | null>(null);
|
||||
const [selectedSourceEnvironment, setSelectedSourceEnvironment] = useState('');
|
||||
|
||||
const [integration, setIntegration] = useState<Integration | null>(null);
|
||||
const [environments, setEnvironments] = useState<
|
||||
{
|
||||
name: string;
|
||||
slug: string;
|
||||
}[]
|
||||
>([]);
|
||||
const [environment, setEnvironment] = useState('');
|
||||
const [vaultBaseUrl, setVaultBaseUrl] = useState('');
|
||||
const [vaultBaseUrlErrorText, setVaultBaseUrlErrorText] = useState('');
|
||||
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
try {
|
||||
if (state === localStorage.getItem('latestCSRFToken')) {
|
||||
localStorage.removeItem('latestCSRFToken');
|
||||
if (state !== localStorage.getItem('latestCSRFToken')) return;
|
||||
localStorage.removeItem('latestCSRFToken');
|
||||
|
||||
const integrationDetails = await AuthorizeIntegration({
|
||||
workspaceId: localStorage.getItem('projectData.id') as string,
|
||||
code: code as string,
|
||||
integration: 'azure-key-vault',
|
||||
});
|
||||
|
||||
setIntegration(integrationDetails.integration);
|
||||
|
||||
const workspaceId = localStorage.getItem('projectData.id');
|
||||
if (!workspaceId) return;
|
||||
|
||||
const workspace = await getAWorkspace(workspaceId);
|
||||
setEnvironment(workspace.environments[0].slug);
|
||||
setEnvironments(workspace.environments);
|
||||
|
||||
}
|
||||
setIntegrationAuth(await AuthorizeIntegration({
|
||||
workspaceId: localStorage.getItem('projectData.id') as string,
|
||||
code: code as string,
|
||||
integration: 'azure-key-vault',
|
||||
}));
|
||||
} catch (error) {
|
||||
console.error('Azure Key Vault integration error: ', error);
|
||||
}
|
||||
})();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (workspaceResult && workspaceResult.data) {
|
||||
setSelectedSourceEnvironment(workspaceResult.data.environments[0].slug);
|
||||
}
|
||||
}, [workspaceResult]);
|
||||
|
||||
const handleButtonClick = async () => {
|
||||
try {
|
||||
@@ -94,17 +77,13 @@ export default function AzureKeyVault() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!integration) return;
|
||||
if (!integrationAuth?._id) return;
|
||||
|
||||
setIsLoading(true);
|
||||
await updateIntegration({
|
||||
integrationId: integration._id,
|
||||
await createIntegration({
|
||||
integrationAuthId: integrationAuth?._id,
|
||||
isActive: true,
|
||||
environment,
|
||||
app: vaultBaseUrl,
|
||||
appId: null,
|
||||
targetEnvironment: null,
|
||||
owner: null
|
||||
app: vaultBaseUrl
|
||||
});
|
||||
setIsLoading(false);
|
||||
|
||||
@@ -117,7 +96,11 @@ export default function AzureKeyVault() {
|
||||
}
|
||||
}
|
||||
|
||||
return (integration && environments.length > 0) ? (
|
||||
if (!workspaceResult) return <div />
|
||||
|
||||
const { data: w } = workspaceResult;
|
||||
|
||||
return (integrationAuth && w && selectedSourceEnvironment) ? (
|
||||
<div className="h-full w-full flex justify-center items-center">
|
||||
<Card className="max-w-md p-8 rounded-md">
|
||||
<CardTitle className='text-center'>Azure Key Vault Integration</CardTitle>
|
||||
@@ -126,13 +109,13 @@ export default function AzureKeyVault() {
|
||||
className='mt-4'
|
||||
>
|
||||
<Select
|
||||
value={environment}
|
||||
onValueChange={(val) => setEnvironment(val)}
|
||||
value={selectedSourceEnvironment}
|
||||
onValueChange={(val) => setSelectedSourceEnvironment(val)}
|
||||
className='w-full border border-mineshaft-500'
|
||||
>
|
||||
{environments.map((e) => (
|
||||
<SelectItem value={e.slug} key={`azure-key-vault-environment-${e.slug}`}>
|
||||
{e.name}
|
||||
{w?.environments.map((sourceEnvironment) => (
|
||||
<SelectItem value={sourceEnvironment.slug} key={`azure-key-vault-environment-${sourceEnvironment.slug}`}>
|
||||
{sourceEnvironment.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</Select>
|
||||
|
||||
+131
-13
@@ -1,41 +1,159 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import queryString from 'query-string';
|
||||
|
||||
import { getTranslatedServerSideProps } from '@app/components/utilities/withTranslateProps';
|
||||
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
CardTitle,
|
||||
FormControl,
|
||||
Select,
|
||||
SelectItem
|
||||
} from '../components/v2';
|
||||
import AuthorizeIntegration from './api/integrations/authorizeIntegration';
|
||||
import getIntegrationApps from './api/integrations/GetIntegrationApps';
|
||||
import getAWorkspace from './api/workspace/getAWorkspace';
|
||||
|
||||
interface Integration {
|
||||
_id: string;
|
||||
isActive: boolean;
|
||||
app: string | null;
|
||||
appId: string | null;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
environment: string;
|
||||
integration: string;
|
||||
targetEnvironment: string;
|
||||
workspace: string;
|
||||
integrationAuth: string;
|
||||
}
|
||||
|
||||
interface IntegrationApp {
|
||||
name: string;
|
||||
appId?: string;
|
||||
owner?: string;
|
||||
}
|
||||
|
||||
export default function Heroku() {
|
||||
const router = useRouter();
|
||||
const parsedUrl = queryString.parse(router.asPath.split('?')[1]);
|
||||
const {code} = parsedUrl;
|
||||
const {state} = parsedUrl;
|
||||
const { code } = parsedUrl;
|
||||
const { state } = parsedUrl;
|
||||
|
||||
const [integration, setIntegration] = useState<Integration | null>(null);
|
||||
const [environments, setEnvironments] = useState<
|
||||
{
|
||||
name: string;
|
||||
slug: string;
|
||||
}[]
|
||||
>([]);
|
||||
const [environment, setEnvironment] = useState('');
|
||||
const [app, setApp] = useState('');
|
||||
const [apps, setApps] = useState<IntegrationApp[]>([]);
|
||||
|
||||
/**
|
||||
* Here we forward to the default workspace if a user opens this url
|
||||
*/
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
try {
|
||||
if (state === localStorage.getItem('latestCSRFToken')) {
|
||||
localStorage.removeItem('latestCSRFToken');
|
||||
await AuthorizeIntegration({
|
||||
const integrationDetails = await AuthorizeIntegration({
|
||||
workspaceId: localStorage.getItem('projectData.id') as string,
|
||||
code: code as string,
|
||||
integration: 'heroku',
|
||||
});
|
||||
router.push(
|
||||
`/integrations/${ localStorage.getItem('projectData.id')}`
|
||||
);
|
||||
|
||||
setIntegration(integrationDetails.integration);
|
||||
|
||||
const workspaceId = localStorage.getItem('projectData.id');
|
||||
if (!workspaceId) return;
|
||||
|
||||
const workspace = await getAWorkspace(workspaceId);
|
||||
setEnvironment(workspace.environments[0].slug);
|
||||
setEnvironments(workspace.environments);
|
||||
|
||||
const tempApps: [IntegrationApp] = await getIntegrationApps({
|
||||
integrationAuthId: integrationDetails.integration.integrationAuth
|
||||
});
|
||||
|
||||
console.log('tempApps: ', tempApps);
|
||||
setApp(tempApps[0].name);
|
||||
setApps(tempApps);
|
||||
|
||||
// router.push(
|
||||
// `/integrations/${ localStorage.getItem('projectData.id')}`
|
||||
// );
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Heroku integration error: ', error);
|
||||
}
|
||||
})();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
const handleButtonClick = async () => {
|
||||
try {
|
||||
console.log('handleButtonClick');
|
||||
console.log('project environment: ', environment);
|
||||
console.log('app', app);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('integration: ', integration);
|
||||
console.log('environments: ', environments);
|
||||
console.log('apps: ', apps);
|
||||
|
||||
return <div />;
|
||||
return (integration && environments.length > 0 && apps.length > 0) ? (
|
||||
<div className="h-full w-full flex justify-center items-center">
|
||||
<Card className="max-w-md p-8 rounded-md">
|
||||
<CardTitle className='text-center'>Heroku Integration</CardTitle>
|
||||
<FormControl
|
||||
label="Project Environment"
|
||||
className='mt-4'
|
||||
>
|
||||
<Select
|
||||
value={environment}
|
||||
onValueChange={(val) => setEnvironment(val)}
|
||||
className='w-full border border-mineshaft-500'
|
||||
>
|
||||
{environments.map((e) => (
|
||||
<SelectItem value={e.slug} key={`heroku-environment-${e.slug}`}>
|
||||
{e.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
<FormControl
|
||||
label="Heroku App"
|
||||
className='mt-4'
|
||||
>
|
||||
<Select
|
||||
value={app}
|
||||
onValueChange={(val) => setApp(val)}
|
||||
className='w-full border border-mineshaft-500'
|
||||
>
|
||||
{apps.map((a) => (
|
||||
<SelectItem value={a.name} key={`heroku-environment-${a.name}`}>
|
||||
{a.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
<Button
|
||||
onClick={handleButtonClick}
|
||||
color="mineshaft"
|
||||
className='mt-4'
|
||||
isLoading={isLoading}
|
||||
>
|
||||
Create Integration
|
||||
</Button>
|
||||
</Card>
|
||||
</div>
|
||||
) : <div>Hello</div>
|
||||
}
|
||||
|
||||
Heroku.requireAuth = true;
|
||||
|
||||
export const getServerSideProps = getTranslatedServerSideProps(['integrations']);
|
||||
@@ -235,7 +235,9 @@ export default function Integrations() {
|
||||
setIntegrationAuths([...integrationAuths, integrationAuth])
|
||||
|
||||
const integration = await createIntegration({
|
||||
integrationAuthId: integrationAuth._id
|
||||
integrationAuthId: integrationAuth._id,
|
||||
isActive: false,
|
||||
app: null
|
||||
});
|
||||
|
||||
setIntegrations([...integrations, integration]);
|
||||
|
||||
Reference in New Issue
Block a user