mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-14 10:29:52 +00:00
Merge branch 'heads/main' into daniel/fips-initative
This commit is contained in:
@@ -1,222 +0,0 @@
|
||||
import { useEffect } from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { FaGithub } from "react-icons/fa";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { z } from "zod";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
Button,
|
||||
FormControl,
|
||||
Input,
|
||||
TextArea
|
||||
} from "@app/components/v2";
|
||||
import { useToggle } from "@app/hooks";
|
||||
import { useUpdateServerConfig } from "@app/hooks/api";
|
||||
import { AdminIntegrationsConfig } from "@app/hooks/api/admin/types";
|
||||
|
||||
const gitHubAppFormSchema = z.object({
|
||||
clientId: z.string(),
|
||||
clientSecret: z.string(),
|
||||
appSlug: z.string(),
|
||||
appId: z.string(),
|
||||
privateKey: z.string()
|
||||
});
|
||||
|
||||
type TGitHubAppConnectionForm = z.infer<typeof gitHubAppFormSchema>;
|
||||
|
||||
type Props = {
|
||||
adminIntegrationsConfig?: AdminIntegrationsConfig;
|
||||
};
|
||||
|
||||
export const GitHubAppConnectionForm = ({ adminIntegrationsConfig }: Props) => {
|
||||
const { mutateAsync: updateAdminServerConfig } = useUpdateServerConfig();
|
||||
const [isGitHubAppClientSecretFocused, setIsGitHubAppClientSecretFocused] = useToggle();
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
setValue,
|
||||
formState: { isSubmitting, isDirty }
|
||||
} = useForm<TGitHubAppConnectionForm>({
|
||||
resolver: zodResolver(gitHubAppFormSchema)
|
||||
});
|
||||
|
||||
const onSubmit = async (data: TGitHubAppConnectionForm) => {
|
||||
await updateAdminServerConfig({
|
||||
gitHubAppConnectionClientId: data.clientId,
|
||||
gitHubAppConnectionClientSecret: data.clientSecret,
|
||||
gitHubAppConnectionSlug: data.appSlug,
|
||||
gitHubAppConnectionId: data.appId,
|
||||
gitHubAppConnectionPrivateKey: data.privateKey
|
||||
});
|
||||
|
||||
createNotification({
|
||||
text: "Updated GitHub app connection configuration. It can take up to 5 minutes to take effect.",
|
||||
type: "success"
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (adminIntegrationsConfig) {
|
||||
setValue("clientId", adminIntegrationsConfig.gitHubAppConnection.clientId);
|
||||
setValue("clientSecret", adminIntegrationsConfig.gitHubAppConnection.clientSecret);
|
||||
setValue("appSlug", adminIntegrationsConfig.gitHubAppConnection.appSlug);
|
||||
setValue("appId", adminIntegrationsConfig.gitHubAppConnection.appId);
|
||||
setValue("privateKey", adminIntegrationsConfig.gitHubAppConnection.privateKey);
|
||||
}
|
||||
}, [adminIntegrationsConfig]);
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<Accordion type="single" collapsible className="w-full">
|
||||
<AccordionItem value="github-app-integration" className="data-[state=open]:border-none">
|
||||
<AccordionTrigger className="flex h-fit w-full justify-start rounded-md border border-mineshaft-500 bg-mineshaft-700 px-4 py-6 text-sm transition-colors data-[state=open]:rounded-b-none">
|
||||
<div className="text-md group order-1 ml-3 flex items-center gap-2">
|
||||
<FaGithub className="text-lg group-hover:text-primary-400" />
|
||||
<div className="text-[15px] font-semibold">GitHub App</div>
|
||||
</div>
|
||||
</AccordionTrigger>
|
||||
<AccordionContent childrenClassName="px-0 py-0">
|
||||
<div className="flex w-full flex-col justify-start rounded-md rounded-t-none border border-t-0 border-mineshaft-500 bg-mineshaft-700 px-4 py-4">
|
||||
<div className="mb-2 max-w-lg text-sm text-mineshaft-300">
|
||||
Step 1: Create and configure GitHub App. Please refer to the documentation below for
|
||||
more information.
|
||||
</div>
|
||||
<div className="mb-6">
|
||||
<a
|
||||
href="https://infisical.com/docs/integrations/app-connections/github#self-hosted-instance"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Button colorSchema="secondary">Documentation</Button>
|
||||
</a>
|
||||
</div>
|
||||
<div className="mb-4 max-w-lg text-sm text-mineshaft-300">
|
||||
Step 2: Configure your instance-wide settings to enable GitHub App connections. Copy
|
||||
the credentials from your GitHub App's settings page.
|
||||
</div>
|
||||
<Controller
|
||||
control={control}
|
||||
name="clientId"
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Client ID"
|
||||
className="w-96"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
>
|
||||
<Input
|
||||
{...field}
|
||||
value={field.value || ""}
|
||||
type="text"
|
||||
onChange={(e) => field.onChange(e.target.value)}
|
||||
/>
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
control={control}
|
||||
name="clientSecret"
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Client Secret"
|
||||
tooltipText="You can find your Client Secret in the GitHub App's settings under 'Client secrets'."
|
||||
className="w-96"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
>
|
||||
<Input
|
||||
{...field}
|
||||
value={field.value || ""}
|
||||
type={isGitHubAppClientSecretFocused ? "text" : "password"}
|
||||
onFocus={() => setIsGitHubAppClientSecretFocused.on()}
|
||||
onBlur={() => setIsGitHubAppClientSecretFocused.off()}
|
||||
onChange={(e) => field.onChange(e.target.value)}
|
||||
/>
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Controller
|
||||
control={control}
|
||||
name="appSlug"
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="App Slug"
|
||||
tooltipText="The GitHub App slug from the app's URL (e.g., 'my-app' from github.com/apps/my-app)."
|
||||
className="w-96"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
>
|
||||
<Input
|
||||
{...field}
|
||||
value={field.value || ""}
|
||||
type="text"
|
||||
onChange={(e) => field.onChange(e.target.value)}
|
||||
/>
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Controller
|
||||
control={control}
|
||||
name="appId"
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="App ID"
|
||||
tooltipText="The numeric App ID found in your GitHub App's settings."
|
||||
className="w-96"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
>
|
||||
<Input
|
||||
{...field}
|
||||
value={field.value || ""}
|
||||
type="text"
|
||||
onChange={(e) => field.onChange(e.target.value)}
|
||||
/>
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Controller
|
||||
control={control}
|
||||
name="privateKey"
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Private Key"
|
||||
tooltipText="The private key generated for your GitHub App (PEM format)."
|
||||
className="w-96"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
>
|
||||
<TextArea
|
||||
{...field}
|
||||
value={field.value || ""}
|
||||
className="min-h-32"
|
||||
onChange={(e) => field.onChange(e.target.value)}
|
||||
/>
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
<div>
|
||||
<Button
|
||||
className="mt-2"
|
||||
type="submit"
|
||||
isLoading={isSubmitting}
|
||||
isDisabled={isSubmitting || !isDirty}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
@@ -5,23 +5,17 @@ import { ROUTE_PATHS } from "@app/const/routes";
|
||||
import { useGetAdminIntegrationsConfig } from "@app/hooks/api";
|
||||
import { AdminIntegrationsConfig } from "@app/hooks/api/admin/types";
|
||||
|
||||
import { GitHubAppConnectionForm } from "./GitHubAppConnectionForm";
|
||||
import { MicrosoftTeamsIntegrationForm } from "./MicrosoftTeamsIntegrationForm";
|
||||
import { SlackIntegrationForm } from "./SlackIntegrationForm";
|
||||
|
||||
enum IntegrationTabSections {
|
||||
Workflow = "workflow",
|
||||
AppConnections = "app-connections"
|
||||
Workflow = "workflow"
|
||||
}
|
||||
|
||||
interface WorkflowTabProps {
|
||||
adminIntegrationsConfig: AdminIntegrationsConfig;
|
||||
}
|
||||
|
||||
interface AppConnectionsTabProps {
|
||||
adminIntegrationsConfig: AdminIntegrationsConfig;
|
||||
}
|
||||
|
||||
const WorkflowTab = ({ adminIntegrationsConfig }: WorkflowTabProps) => (
|
||||
<div className="flex flex-col gap-2">
|
||||
<SlackIntegrationForm adminIntegrationsConfig={adminIntegrationsConfig} />
|
||||
@@ -29,12 +23,6 @@ const WorkflowTab = ({ adminIntegrationsConfig }: WorkflowTabProps) => (
|
||||
</div>
|
||||
);
|
||||
|
||||
const AppConnectionsTab = ({ adminIntegrationsConfig }: AppConnectionsTabProps) => (
|
||||
<div className="flex flex-col gap-2">
|
||||
<GitHubAppConnectionForm adminIntegrationsConfig={adminIntegrationsConfig} />
|
||||
</div>
|
||||
);
|
||||
|
||||
export const IntegrationsPageForm = () => {
|
||||
const { data: adminIntegrationsConfig } = useGetAdminIntegrationsConfig();
|
||||
|
||||
@@ -59,11 +47,6 @@ export const IntegrationsPageForm = () => {
|
||||
key: IntegrationTabSections.Workflow,
|
||||
label: "Workflows",
|
||||
component: WorkflowTab
|
||||
},
|
||||
{
|
||||
key: IntegrationTabSections.AppConnections,
|
||||
label: "App Connections",
|
||||
component: AppConnectionsTab
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
+1
-5
@@ -39,10 +39,6 @@ export const OrgMembersSection = () => {
|
||||
const { mutateAsync: deleteMutateAsync } = useDeleteOrgMembership();
|
||||
const { mutateAsync: updateOrgMembership } = useUpdateOrgMembership();
|
||||
|
||||
const isMoreUsersAllowed = subscription?.memberLimit
|
||||
? subscription.membersUsed < subscription.memberLimit
|
||||
: true;
|
||||
|
||||
const isMoreIdentitiesAllowed = subscription?.identityLimit
|
||||
? subscription.identitiesUsed < subscription.identityLimit
|
||||
: true;
|
||||
@@ -58,7 +54,7 @@ export const OrgMembersSection = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((!isMoreUsersAllowed || !isMoreIdentitiesAllowed) && !isEnterprise) {
|
||||
if (!isMoreIdentitiesAllowed && !isEnterprise) {
|
||||
handlePopUpOpen("upgradePlan", {
|
||||
description: "You can add more members if you upgrade your Infisical plan."
|
||||
});
|
||||
|
||||
-18
@@ -1,6 +1,3 @@
|
||||
import { Link } from "@tanstack/react-router";
|
||||
|
||||
import { NoticeBannerV2 } from "@app/components/v2/NoticeBannerV2/NoticeBannerV2";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/context";
|
||||
import { withPermission } from "@app/hoc";
|
||||
|
||||
@@ -11,21 +8,6 @@ export const OrgSecurityTab = withPermission(
|
||||
() => {
|
||||
return (
|
||||
<>
|
||||
<NoticeBannerV2
|
||||
className="mx-auto mb-4"
|
||||
titleClassName="text-base"
|
||||
title="Single Sign-On (SSO) Settings"
|
||||
>
|
||||
<p className="mt-1 text-mineshaft-300">
|
||||
SSO Settings have been relocated:{" "}
|
||||
<Link
|
||||
className="text-mineshaft-200 underline underline-offset-2"
|
||||
to="/organization/sso"
|
||||
>
|
||||
Click here to view SSO Settings
|
||||
</Link>
|
||||
</p>
|
||||
</NoticeBannerV2>
|
||||
<OrgGenericAuthSection />
|
||||
<OrgUserAccessTokenLimitSection />
|
||||
</>
|
||||
|
||||
+13
-1
@@ -9,8 +9,10 @@ import { ImportTab } from "../ImportTab";
|
||||
import { KmipTab } from "../KmipTab/OrgKmipTab";
|
||||
import { OrgEncryptionTab } from "../OrgEncryptionTab";
|
||||
import { OrgGeneralTab } from "../OrgGeneralTab";
|
||||
import { OrgProvisioningTab } from "../OrgProvisioningTab";
|
||||
import { OrgSecurityTab } from "../OrgSecurityTab";
|
||||
import { OrgWorkflowIntegrationTab } from "../OrgWorkflowIntegrationTab/OrgWorkflowIntegrationTab";
|
||||
import { OrgSsoTab } from "../OrgSsoTab";
|
||||
import { OrgWorkflowIntegrationTab } from "../OrgWorkflowIntegrationTab";
|
||||
import { ProjectTemplatesTab } from "../ProjectTemplatesTab";
|
||||
|
||||
export const OrgTabGroup = () => {
|
||||
@@ -19,6 +21,16 @@ export const OrgTabGroup = () => {
|
||||
});
|
||||
const tabs = [
|
||||
{ name: "General", key: "tab-org-general", component: OrgGeneralTab },
|
||||
{
|
||||
name: "SSO",
|
||||
key: "sso-settings",
|
||||
component: OrgSsoTab
|
||||
},
|
||||
{
|
||||
name: "Provisioning",
|
||||
key: "provisioning-settings",
|
||||
component: OrgProvisioningTab
|
||||
},
|
||||
{ name: "Security", key: "tab-org-security", component: OrgSecurityTab },
|
||||
{ name: "Encryption", key: "tab-org-encryption", component: OrgEncryptionTab },
|
||||
{
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
export * from "./OrgWorkflowIntegrationTab";
|
||||
@@ -1,21 +0,0 @@
|
||||
import { Helmet } from "react-helmet";
|
||||
|
||||
import { PageHeader } from "@app/components/v2";
|
||||
|
||||
import { SsoTabGroup } from "./components/SsoTabGroup";
|
||||
|
||||
export const SsoPage = () => {
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>Single Sign-On (SSO)</title>
|
||||
</Helmet>
|
||||
<div className="flex w-full justify-center bg-bunker-800 text-white">
|
||||
<div className="w-full max-w-7xl">
|
||||
<PageHeader title="Single Sign-On (SSO)" />
|
||||
<SsoTabGroup />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,37 +0,0 @@
|
||||
import { useState } from "react";
|
||||
import { useSearch } from "@tanstack/react-router";
|
||||
|
||||
import { Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
|
||||
import { ROUTE_PATHS } from "@app/const/routes";
|
||||
|
||||
import { OrgProvisioningTab } from "../OrgProvisioningTab";
|
||||
import { OrgSsoTab } from "../OrgSsoTab";
|
||||
|
||||
export const SsoTabGroup = () => {
|
||||
const search = useSearch({
|
||||
from: ROUTE_PATHS.Organization.SsoPage.id
|
||||
});
|
||||
const tabs = [
|
||||
{ name: "General", key: "tab-sso-auth", component: OrgSsoTab },
|
||||
{ name: "Provisioning", key: "tab-sso-identity", component: OrgProvisioningTab }
|
||||
];
|
||||
|
||||
const [selectedTab, setSelectedTab] = useState(search.selectedTab || tabs[0].key);
|
||||
|
||||
return (
|
||||
<Tabs value={selectedTab} onValueChange={setSelectedTab}>
|
||||
<TabList>
|
||||
{tabs.map((tab) => (
|
||||
<Tab value={tab.key} key={tab.key}>
|
||||
{tab.name}
|
||||
</Tab>
|
||||
))}
|
||||
</TabList>
|
||||
{tabs.map(({ key, component: Component }) => (
|
||||
<TabPanel value={key} key={`tab-panel-${key}`}>
|
||||
<Component />
|
||||
</TabPanel>
|
||||
))}
|
||||
</Tabs>
|
||||
);
|
||||
};
|
||||
@@ -1 +0,0 @@
|
||||
export { SsoTabGroup } from "./SsoTabGroup";
|
||||
@@ -1,26 +0,0 @@
|
||||
import { createFileRoute, stripSearchParams } from "@tanstack/react-router";
|
||||
import { zodValidator } from "@tanstack/zod-adapter";
|
||||
import { z } from "zod";
|
||||
|
||||
import { SsoPage } from "./SsoPage";
|
||||
|
||||
const SettingsPageQueryParams = z.object({
|
||||
selectedTab: z.string().catch("")
|
||||
});
|
||||
|
||||
export const Route = createFileRoute(
|
||||
"/_authenticate/_inject-org-details/_org-layout/organization/sso"
|
||||
)({
|
||||
component: SsoPage,
|
||||
validateSearch: zodValidator(SettingsPageQueryParams),
|
||||
search: {
|
||||
middlewares: [stripSearchParams({ selectedTab: "" })]
|
||||
},
|
||||
context: () => ({
|
||||
breadcrumbs: [
|
||||
{
|
||||
label: "Single Sign-On (SSO)"
|
||||
}
|
||||
]
|
||||
})
|
||||
});
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
import { TCloudflareWorkersSync } from "@app/hooks/api/secretSyncs/types/cloudflare-workers-sync";
|
||||
|
||||
import { getSecretSyncDestinationColValues } from "../helpers";
|
||||
import { SecretSyncTableCell } from "../SecretSyncTableCell";
|
||||
|
||||
type Props = {
|
||||
secretSync: TCloudflareWorkersSync;
|
||||
};
|
||||
|
||||
export const CloudflareWorkersSyncDestinationCol = ({ secretSync }: Props) => {
|
||||
const { primaryText, secondaryText } = getSecretSyncDestinationColValues(secretSync);
|
||||
|
||||
return <SecretSyncTableCell primaryText={primaryText} secondaryText={secondaryText} />;
|
||||
};
|
||||
+3
@@ -8,6 +8,7 @@ import { AzureDevOpsSyncDestinationCol } from "./AzureDevOpsSyncDestinationCol";
|
||||
import { AzureKeyVaultDestinationSyncCol } from "./AzureKeyVaultDestinationSyncCol";
|
||||
import { CamundaSyncDestinationCol } from "./CamundaSyncDestinationCol";
|
||||
import { CloudflarePagesSyncDestinationCol } from "./CloudflarePagesSyncDestinationCol";
|
||||
import { CloudflareWorkersSyncDestinationCol } from "./CloudflareWorkersSyncDestinationCol";
|
||||
import { DatabricksSyncDestinationCol } from "./DatabricksSyncDestinationCol";
|
||||
import { FlyioSyncDestinationCol } from "./FlyioSyncDestinationCol";
|
||||
import { GcpSyncDestinationCol } from "./GcpSyncDestinationCol";
|
||||
@@ -75,6 +76,8 @@ export const SecretSyncDestinationCol = ({ secretSync }: Props) => {
|
||||
return <GitLabSyncDestinationCol secretSync={secretSync} />;
|
||||
case SecretSync.CloudflarePages:
|
||||
return <CloudflarePagesSyncDestinationCol secretSync={secretSync} />;
|
||||
case SecretSync.CloudflareWorkers:
|
||||
return <CloudflareWorkersSyncDestinationCol secretSync={secretSync} />;
|
||||
case SecretSync.Zabbix:
|
||||
return <ZabbixSyncDestinationCol secretSync={secretSync} />;
|
||||
case SecretSync.Railway:
|
||||
|
||||
+4
@@ -145,6 +145,10 @@ export const getSecretSyncDestinationColValues = (secretSync: TSecretSync) => {
|
||||
primaryText = destinationConfig.projectName;
|
||||
secondaryText = destinationConfig.environment;
|
||||
break;
|
||||
case SecretSync.CloudflareWorkers:
|
||||
primaryText = destinationConfig.scriptId;
|
||||
secondaryText = "Script ID";
|
||||
break;
|
||||
case SecretSync.Zabbix:
|
||||
if (destinationConfig.scope === ZabbixSyncScope.Host) {
|
||||
primaryText = destinationConfig.hostName;
|
||||
|
||||
+1
-1
@@ -174,7 +174,7 @@ export const SecretOverviewTableRow = ({
|
||||
)}
|
||||
{isSecretEmpty && (
|
||||
<Tooltip content="Empty value">
|
||||
<FontAwesomeIcon size="sm" icon={faCircle} />
|
||||
<FontAwesomeIcon size="sm" icon={faCircle} className="text-yellow" />
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
|
||||
+7
-1
@@ -21,6 +21,7 @@ import {
|
||||
Tag,
|
||||
Tooltip
|
||||
} from "@app/components/v2";
|
||||
import { SecretPathInput } from "@app/components/v2/SecretPathInput";
|
||||
import { useWorkspace } from "@app/context";
|
||||
import { getMemberLabel } from "@app/helpers/members";
|
||||
import { policyDetails } from "@app/helpers/policies";
|
||||
@@ -203,6 +204,7 @@ const Form = ({
|
||||
|
||||
const formUserBypassers = watch("userBypassers");
|
||||
const formGroupBypassers = watch("groupBypassers");
|
||||
const formEnvironment = watch("environment")?.slug;
|
||||
const bypasserCount = (formUserBypassers || []).length + (formGroupBypassers || []).length;
|
||||
|
||||
const handleCreatePolicy = async ({
|
||||
@@ -474,7 +476,11 @@ const Form = ({
|
||||
errorText={error?.message}
|
||||
className="flex-1"
|
||||
>
|
||||
<Input {...field} value={field.value || ""} />
|
||||
<SecretPathInput
|
||||
{...field}
|
||||
value={field.value || ""}
|
||||
environment={formEnvironment}
|
||||
/>
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
|
||||
+8
-2
@@ -338,8 +338,14 @@ export const SecretApprovalRequest = () => {
|
||||
</div>
|
||||
<span className="text-xs leading-3 text-gray-500">
|
||||
Opened {formatDistance(new Date(createdAt), new Date())} ago by{" "}
|
||||
{committerUser?.firstName || ""} {committerUser?.lastName || ""} (
|
||||
{committerUser?.email})
|
||||
{committerUser ? (
|
||||
<>
|
||||
{committerUser?.firstName || ""} {committerUser?.lastName || ""} (
|
||||
{committerUser?.email})
|
||||
</>
|
||||
) : (
|
||||
<span className="text-gray-600">Deleted User</span>
|
||||
)}
|
||||
{!isReviewed && status === "open" && " - Review required"}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
+11
-4
@@ -250,10 +250,17 @@ export const SecretApprovalRequestChanges = ({
|
||||
secretApprovalRequestDetails.isReplicated
|
||||
)}
|
||||
</div>
|
||||
<span className="-mt-1 flex items-center space-x-2 text-xs text-gray-400">
|
||||
By {secretApprovalRequestDetails?.committerUser?.firstName} (
|
||||
{secretApprovalRequestDetails?.committerUser?.email})
|
||||
</span>
|
||||
<p className="-mt-1 text-xs text-gray-400">
|
||||
By{" "}
|
||||
{secretApprovalRequestDetails?.committerUser ? (
|
||||
<>
|
||||
{secretApprovalRequestDetails?.committerUser?.firstName} (
|
||||
{secretApprovalRequestDetails?.committerUser?.email})
|
||||
</>
|
||||
) : (
|
||||
<span className="text-gray-500">Deleted User</span>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
{!hasMerged &&
|
||||
secretApprovalRequestDetails.status === "open" &&
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
import { GenericFieldLabel } from "@app/components/secret-syncs";
|
||||
import { TCloudflareWorkersSync } from "@app/hooks/api/secretSyncs/types/cloudflare-workers-sync";
|
||||
|
||||
type Props = {
|
||||
secretSync: TCloudflareWorkersSync;
|
||||
};
|
||||
|
||||
export const CloudflareWorkersSyncDestinationSection = ({ secretSync }: Props) => {
|
||||
const {
|
||||
destinationConfig: { scriptId }
|
||||
} = secretSync;
|
||||
|
||||
return <GenericFieldLabel label="Script ID">{scriptId}</GenericFieldLabel>;
|
||||
};
|
||||
+4
@@ -19,6 +19,7 @@ import { AzureDevOpsSyncDestinationSection } from "./AzureDevOpsSyncDestinationS
|
||||
import { AzureKeyVaultSyncDestinationSection } from "./AzureKeyVaultSyncDestinationSection";
|
||||
import { CamundaSyncDestinationSection } from "./CamundaSyncDestinationSection";
|
||||
import { CloudflarePagesSyncDestinationSection } from "./CloudflarePagesSyncDestinationSection";
|
||||
import { CloudflareWorkersSyncDestinationSection } from "./CloudflareWorkersSyncDestinationSection";
|
||||
import { DatabricksSyncDestinationSection } from "./DatabricksSyncDestinationSection";
|
||||
import { FlyioSyncDestinationSection } from "./FlyioSyncDestinationSection";
|
||||
import { GcpSyncDestinationSection } from "./GcpSyncDestinationSection";
|
||||
@@ -116,6 +117,9 @@ export const SecretSyncDestinationSection = ({ secretSync, onEditDestination }:
|
||||
case SecretSync.CloudflarePages:
|
||||
DestinationComponents = <CloudflarePagesSyncDestinationSection secretSync={secretSync} />;
|
||||
break;
|
||||
case SecretSync.CloudflareWorkers:
|
||||
DestinationComponents = <CloudflareWorkersSyncDestinationSection secretSync={secretSync} />;
|
||||
break;
|
||||
case SecretSync.Zabbix:
|
||||
DestinationComponents = <ZabbixSyncDestinationSection secretSync={secretSync} />;
|
||||
break;
|
||||
|
||||
+1
@@ -60,6 +60,7 @@ export const SecretSyncOptionsSection = ({ secretSync, onEditOptions }: Props) =
|
||||
case SecretSync.Flyio:
|
||||
case SecretSync.GitLab:
|
||||
case SecretSync.CloudflarePages:
|
||||
case SecretSync.CloudflareWorkers:
|
||||
case SecretSync.Zabbix:
|
||||
case SecretSync.Railway:
|
||||
AdditionalSyncOptionsComponent = null;
|
||||
|
||||
Reference in New Issue
Block a user