mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-14 14:34:09 +00:00
feat(secret-sync): 1Password Secret Sync
This commit is contained in:
+78
@@ -0,0 +1,78 @@
|
||||
import { Controller, useFormContext, useWatch } from "react-hook-form";
|
||||
import { SingleValue } from "react-select";
|
||||
import { faCircleInfo } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
import { SecretSyncConnectionField } from "@app/components/secret-syncs/forms/SecretSyncConnectionField";
|
||||
import { FilterableSelect, FormControl, Tooltip } from "@app/components/v2";
|
||||
import {
|
||||
TOnePassVault,
|
||||
useOnePassConnectionListVaults
|
||||
} from "@app/hooks/api/appConnections/1password";
|
||||
import { SecretSync } from "@app/hooks/api/secretSyncs";
|
||||
|
||||
import { TSecretSyncForm } from "../schemas";
|
||||
|
||||
export const OnePassSyncFields = () => {
|
||||
const { control, setValue } = useFormContext<
|
||||
TSecretSyncForm & { destination: SecretSync.OnePass }
|
||||
>();
|
||||
|
||||
const connectionId = useWatch({ name: "connection.id", control });
|
||||
|
||||
const { data: vaults, isLoading: isVaultsLoading } = useOnePassConnectionListVaults(
|
||||
connectionId,
|
||||
{
|
||||
enabled: Boolean(connectionId)
|
||||
}
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<SecretSyncConnectionField
|
||||
onChange={() => {
|
||||
setValue("destinationConfig.vaultId", "");
|
||||
}}
|
||||
/>
|
||||
|
||||
<Controller
|
||||
name="destinationConfig.vaultId"
|
||||
control={control}
|
||||
render={({ field: { value, onChange }, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
label="Vault"
|
||||
helperText={
|
||||
<Tooltip
|
||||
className="max-w-md"
|
||||
content="Ensure the vault exists in the connection's OnePass instance URL."
|
||||
>
|
||||
<div>
|
||||
<span>Don't see the vault you're looking for?</span>{" "}
|
||||
<FontAwesomeIcon icon={faCircleInfo} className="text-mineshaft-400" />
|
||||
</div>
|
||||
</Tooltip>
|
||||
}
|
||||
>
|
||||
<FilterableSelect
|
||||
menuPlacement="top"
|
||||
isLoading={isVaultsLoading && Boolean(connectionId)}
|
||||
isDisabled={!connectionId}
|
||||
value={vaults?.find((v) => v.id === value) ?? null}
|
||||
onChange={(option) => onChange((option as SingleValue<TOnePassVault>)?.id ?? null)}
|
||||
options={vaults}
|
||||
placeholder="Select a vault..."
|
||||
getOptionLabel={(option) => option.name}
|
||||
getOptionValue={(option) => option.id}
|
||||
/>
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
|
||||
<span className="text-sm text-bunker-300">
|
||||
Not selecting a Build Configuration will sync your secrets to the entire project.
|
||||
</span>
|
||||
</>
|
||||
);
|
||||
};
|
||||
+3
@@ -3,6 +3,7 @@ import { useFormContext } from "react-hook-form";
|
||||
import { SecretSync } from "@app/hooks/api/secretSyncs";
|
||||
|
||||
import { TSecretSyncForm } from "../schemas";
|
||||
import { OnePassSyncFields } from "./1PasswordSyncFields";
|
||||
import { AwsParameterStoreSyncFields } from "./AwsParameterStoreSyncFields";
|
||||
import { AwsSecretsManagerSyncFields } from "./AwsSecretsManagerSyncFields";
|
||||
import { AzureAppConfigurationSyncFields } from "./AzureAppConfigurationSyncFields";
|
||||
@@ -55,6 +56,8 @@ export const SecretSyncDestinationFields = () => {
|
||||
return <TeamCitySyncFields />;
|
||||
case SecretSync.OCIVault:
|
||||
return <OCIVaultSyncFields />;
|
||||
case SecretSync.OnePass:
|
||||
return <OnePassSyncFields />;
|
||||
default:
|
||||
throw new Error(`Unhandled Destination Config Field: ${destination}`);
|
||||
}
|
||||
|
||||
+1
@@ -49,6 +49,7 @@ export const SecretSyncOptionsFields = ({ hideInitialSync }: Props) => {
|
||||
case SecretSync.Windmill:
|
||||
case SecretSync.HCVault:
|
||||
case SecretSync.TeamCity:
|
||||
case SecretSync.OnePass:
|
||||
case SecretSync.OCIVault:
|
||||
AdditionalSyncOptionsFieldsComponent = null;
|
||||
break;
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import { useFormContext } from "react-hook-form";
|
||||
|
||||
import { TSecretSyncForm } from "@app/components/secret-syncs/forms/schemas";
|
||||
import { GenericFieldLabel } from "@app/components/v2";
|
||||
import { SecretSync } from "@app/hooks/api/secretSyncs";
|
||||
|
||||
export const OnePassSyncReviewFields = () => {
|
||||
const { watch } = useFormContext<TSecretSyncForm & { destination: SecretSync.OnePass }>();
|
||||
const vaultId = watch("destinationConfig.vaultId");
|
||||
|
||||
return (
|
||||
<>
|
||||
<GenericFieldLabel label="Vault ID">{vaultId}</GenericFieldLabel>
|
||||
</>
|
||||
);
|
||||
};
|
||||
+4
@@ -28,6 +28,7 @@ import { TeamCitySyncReviewFields } from "./TeamCitySyncReviewFields";
|
||||
import { TerraformCloudSyncReviewFields } from "./TerraformCloudSyncReviewFields";
|
||||
import { VercelSyncReviewFields } from "./VercelSyncReviewFields";
|
||||
import { WindmillSyncReviewFields } from "./WindmillSyncReviewFields";
|
||||
import { OnePassSyncReviewFields } from "./OnePassSyncReviewFields";
|
||||
|
||||
export const SecretSyncReviewFields = () => {
|
||||
const { watch } = useFormContext<TSecretSyncForm>();
|
||||
@@ -96,6 +97,9 @@ export const SecretSyncReviewFields = () => {
|
||||
case SecretSync.OCIVault:
|
||||
DestinationFieldsComponent = <OCIVaultSyncReviewFields />;
|
||||
break;
|
||||
case SecretSync.OnePass:
|
||||
DestinationFieldsComponent = <OnePassSyncReviewFields />;
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unhandled Destination Review Fields: ${destination}`);
|
||||
}
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { BaseSecretSyncSchema } from "@app/components/secret-syncs/forms/schemas/base-secret-sync-schema";
|
||||
import { SecretSync } from "@app/hooks/api/secretSyncs";
|
||||
|
||||
export const OnePassSyncDestinationSchema = BaseSecretSyncSchema().merge(
|
||||
z.object({
|
||||
destination: z.literal(SecretSync.OnePass),
|
||||
destinationConfig: z.object({
|
||||
vaultId: z.string().trim().min(1, "Vault ID required")
|
||||
})
|
||||
})
|
||||
);
|
||||
@@ -1,5 +1,6 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { OnePassSyncDestinationSchema } from "./1password-sync-destination-schema";
|
||||
import { AwsParameterStoreSyncDestinationSchema } from "./aws-parameter-store-sync-destination-schema";
|
||||
import { AwsSecretsManagerSyncDestinationSchema } from "./aws-secrets-manager-sync-destination-schema";
|
||||
import { AzureAppConfigurationSyncDestinationSchema } from "./azure-app-configuration-sync-destination-schema";
|
||||
@@ -31,7 +32,8 @@ const SecretSyncUnionSchema = z.discriminatedUnion("destination", [
|
||||
WindmillSyncDestinationSchema,
|
||||
HCVaultSyncDestinationSchema,
|
||||
TeamCitySyncDestinationSchema,
|
||||
OCIVaultSyncDestinationSchema
|
||||
OCIVaultSyncDestinationSchema,
|
||||
OnePassSyncDestinationSchema
|
||||
]);
|
||||
|
||||
export const SecretSyncFormSchema = SecretSyncUnionSchema;
|
||||
|
||||
@@ -23,10 +23,10 @@ import {
|
||||
HumanitecConnectionMethod,
|
||||
LdapConnectionMethod,
|
||||
MsSqlConnectionMethod,
|
||||
OnePassConnectionMethod,
|
||||
PostgresConnectionMethod,
|
||||
TAppConnection,
|
||||
TeamCityConnectionMethod,
|
||||
OnePassConnectionMethod,
|
||||
TerraformCloudConnectionMethod,
|
||||
VercelConnectionMethod,
|
||||
WindmillConnectionMethod
|
||||
|
||||
@@ -51,6 +51,10 @@ export const SECRET_SYNC_MAP: Record<SecretSync, { name: string; image: string }
|
||||
[SecretSync.OCIVault]: {
|
||||
name: "OCI Vault",
|
||||
image: "Oracle.png"
|
||||
},
|
||||
[SecretSync.OnePass]: {
|
||||
name: "1Password",
|
||||
image: "1Password.png"
|
||||
}
|
||||
};
|
||||
|
||||
@@ -69,7 +73,8 @@ export const SECRET_SYNC_CONNECTION_MAP: Record<SecretSync, AppConnection> = {
|
||||
[SecretSync.Windmill]: AppConnection.Windmill,
|
||||
[SecretSync.HCVault]: AppConnection.HCVault,
|
||||
[SecretSync.TeamCity]: AppConnection.TeamCity,
|
||||
[SecretSync.OCIVault]: AppConnection.OCI
|
||||
[SecretSync.OCIVault]: AppConnection.OCI,
|
||||
[SecretSync.OnePass]: AppConnection.OnePass
|
||||
};
|
||||
|
||||
export const SECRET_SYNC_INITIAL_SYNC_BEHAVIOR_MAP: Record<
|
||||
|
||||
@@ -88,6 +88,10 @@ export type TOCIConnectionOption = TAppConnectionOptionBase & {
|
||||
app: AppConnection.OCI;
|
||||
};
|
||||
|
||||
export type TOnePassConnectionOption = TAppConnectionOptionBase & {
|
||||
app: AppConnection.OnePass;
|
||||
};
|
||||
|
||||
export type TAppConnectionOption =
|
||||
| TAwsConnectionOption
|
||||
| TGitHubConnectionOption
|
||||
@@ -106,7 +110,8 @@ export type TAppConnectionOption =
|
||||
| TAuth0ConnectionOption
|
||||
| THCVaultConnectionOption
|
||||
| TTeamCityConnectionOption
|
||||
| TOCIConnectionOption;
|
||||
| TOCIConnectionOption
|
||||
| TOnePassConnectionOption;
|
||||
|
||||
export type TAppConnectionOptionMap = {
|
||||
[AppConnection.AWS]: TAwsConnectionOption;
|
||||
@@ -128,4 +133,5 @@ export type TAppConnectionOptionMap = {
|
||||
[AppConnection.LDAP]: TLdapConnectionOption;
|
||||
[AppConnection.TeamCity]: TTeamCityConnectionOption;
|
||||
[AppConnection.OCI]: TOCIConnectionOption;
|
||||
[AppConnection.OnePass]: TOnePassConnectionOption;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { AppConnection } from "../enums";
|
||||
import { TAppConnectionOption } from "./app-options";
|
||||
import { TOnePassConnection } from "./1password-connection";
|
||||
import { TAppConnectionOption } from "./app-options";
|
||||
import { TAuth0Connection } from "./auth0-connection";
|
||||
import { TAwsConnection } from "./aws-connection";
|
||||
import { TAzureAppConfigurationConnection } from "./azure-app-configuration-connection";
|
||||
|
||||
@@ -13,7 +13,8 @@ export enum SecretSync {
|
||||
Windmill = "windmill",
|
||||
HCVault = "hashicorp-vault",
|
||||
TeamCity = "teamcity",
|
||||
OCIVault = "oci-vault"
|
||||
OCIVault = "oci-vault",
|
||||
OnePass = "1password"
|
||||
}
|
||||
|
||||
export enum SecretSyncStatus {
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { AppConnection } from "@app/hooks/api/appConnections/enums";
|
||||
import { SecretSync } from "@app/hooks/api/secretSyncs";
|
||||
import { TRootSecretSync } from "@app/hooks/api/secretSyncs/types/root-sync";
|
||||
|
||||
export type TOnePassSync = TRootSecretSync & {
|
||||
destination: SecretSync.OnePass;
|
||||
destinationConfig: {
|
||||
vaultId: string;
|
||||
};
|
||||
connection: {
|
||||
app: AppConnection.OnePass;
|
||||
name: string;
|
||||
id: string;
|
||||
};
|
||||
};
|
||||
@@ -1,6 +1,7 @@
|
||||
import { SecretSync, SecretSyncImportBehavior } from "@app/hooks/api/secretSyncs";
|
||||
import { DiscriminativePick } from "@app/types";
|
||||
|
||||
import { TOnePassSync } from "./1password-sync";
|
||||
import { TAwsParameterStoreSync } from "./aws-parameter-store-sync";
|
||||
import { TAwsSecretsManagerSync } from "./aws-secrets-manager-sync";
|
||||
import { TAzureAppConfigurationSync } from "./azure-app-configuration-sync";
|
||||
@@ -38,7 +39,8 @@ export type TSecretSync =
|
||||
| TWindmillSync
|
||||
| THCVaultSync
|
||||
| TTeamCitySync
|
||||
| TOCIVaultSync;
|
||||
| TOCIVaultSync
|
||||
| TOnePassSync;
|
||||
|
||||
export type TListSecretSyncs = { secretSyncs: TSecretSync[] };
|
||||
|
||||
|
||||
+1
-1
@@ -9,6 +9,7 @@ import { AppConnection } from "@app/hooks/api/appConnections/enums";
|
||||
import { DiscriminativePick } from "@app/types";
|
||||
|
||||
import { AppConnectionHeader } from "../AppConnectionHeader";
|
||||
import { OnePassConnectionForm } from "./1PasswordConnectionForm";
|
||||
import { Auth0ConnectionForm } from "./Auth0ConnectionForm";
|
||||
import { AwsConnectionForm } from "./AwsConnectionForm";
|
||||
import { AzureAppConfigurationConnectionForm } from "./AzureAppConfigurationConnectionForm";
|
||||
@@ -25,7 +26,6 @@ import { MsSqlConnectionForm } from "./MsSqlConnectionForm";
|
||||
import { OCIConnectionForm } from "./OCIConnectionForm";
|
||||
import { PostgresConnectionForm } from "./PostgresConnectionForm";
|
||||
import { TeamCityConnectionForm } from "./TeamCityConnectionForm";
|
||||
import { OnePassConnectionForm } from "./1PasswordConnectionForm";
|
||||
import { TerraformCloudConnectionForm } from "./TerraformCloudConnectionForm";
|
||||
import { VercelConnectionForm } from "./VercelConnectionForm";
|
||||
import { WindmillConnectionForm } from "./WindmillConnectionForm";
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
import { TOnePassSync } from "@app/hooks/api/secretSyncs/types/1password-sync";
|
||||
|
||||
import { getSecretSyncDestinationColValues } from "../helpers";
|
||||
import { SecretSyncTableCell } from "../SecretSyncTableCell";
|
||||
|
||||
type Props = {
|
||||
secretSync: TOnePassSync;
|
||||
};
|
||||
|
||||
export const OnePassSyncDestinationCol = ({ secretSync }: Props) => {
|
||||
const { primaryText, secondaryText } = getSecretSyncDestinationColValues(secretSync);
|
||||
|
||||
return <SecretSyncTableCell primaryText={primaryText} secondaryText={secondaryText} />;
|
||||
};
|
||||
+3
@@ -1,5 +1,6 @@
|
||||
import { SecretSync, TSecretSync } from "@app/hooks/api/secretSyncs";
|
||||
|
||||
import { OnePassSyncDestinationCol } from "./1PasswordSyncDestinationCol";
|
||||
import { AwsParameterStoreSyncDestinationCol } from "./AwsParameterStoreSyncDestinationCol";
|
||||
import { AwsSecretsManagerSyncDestinationCol } from "./AwsSecretsManagerSyncDestinationCol";
|
||||
import { AzureAppConfigurationDestinationSyncCol } from "./AzureAppConfigurationDestinationSyncCol";
|
||||
@@ -52,6 +53,8 @@ export const SecretSyncDestinationCol = ({ secretSync }: Props) => {
|
||||
return <TeamCitySyncDestinationCol secretSync={secretSync} />;
|
||||
case SecretSync.OCIVault:
|
||||
return <OCIVaultSyncDestinationCol secretSync={secretSync} />;
|
||||
case SecretSync.OnePass:
|
||||
return <OnePassSyncDestinationCol secretSync={secretSync} />;
|
||||
default:
|
||||
throw new Error(
|
||||
`Unhandled Secret Sync Destination Col: ${(secretSync as TSecretSync).destination}`
|
||||
|
||||
+4
@@ -106,6 +106,10 @@ export const getSecretSyncDestinationColValues = (secretSync: TSecretSync) => {
|
||||
primaryText = destinationConfig.compartmentOcid;
|
||||
secondaryText = destinationConfig.vaultOcid;
|
||||
break;
|
||||
case SecretSync.OnePass:
|
||||
primaryText = destinationConfig.vaultId;
|
||||
secondaryText = "Vault ID";
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unhandled Destination Col Values ${destination}`);
|
||||
}
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
import { GenericFieldLabel } from "@app/components/secret-syncs";
|
||||
import { TOnePassSync } from "@app/hooks/api/secretSyncs/types/1password-sync";
|
||||
|
||||
type Props = {
|
||||
secretSync: TOnePassSync;
|
||||
};
|
||||
|
||||
export const OnePassSyncDestinationSection = ({ secretSync }: Props) => {
|
||||
const {
|
||||
destinationConfig: { vaultId }
|
||||
} = secretSync;
|
||||
|
||||
return <GenericFieldLabel label="Vault ID">{vaultId}</GenericFieldLabel>;
|
||||
};
|
||||
+4
@@ -10,6 +10,7 @@ import { ProjectPermissionSecretSyncActions } from "@app/context/ProjectPermissi
|
||||
import { APP_CONNECTION_MAP } from "@app/helpers/appConnections";
|
||||
import { SecretSync, TSecretSync } from "@app/hooks/api/secretSyncs";
|
||||
|
||||
import { OnePassSyncDestinationSection } from "./1PasswordSyncDestinationSection";
|
||||
import { AwsParameterStoreSyncDestinationSection } from "./AwsParameterStoreSyncDestinationSection";
|
||||
import { AwsSecretsManagerSyncDestinationSection } from "./AwsSecretsManagerSyncDestinationSection";
|
||||
import { AzureAppConfigurationSyncDestinationSection } from "./AzureAppConfigurationSyncDestinationSection";
|
||||
@@ -85,6 +86,9 @@ export const SecretSyncDestinationSection = ({ secretSync, onEditDestination }:
|
||||
case SecretSync.OCIVault:
|
||||
DestinationComponents = <OCIVaultSyncDestinationSection secretSync={secretSync} />;
|
||||
break;
|
||||
case SecretSync.OnePass:
|
||||
DestinationComponents = <OnePassSyncDestinationSection secretSync={secretSync} />;
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unhandled Destination Section components: ${destination}`);
|
||||
}
|
||||
|
||||
+1
@@ -50,6 +50,7 @@ export const SecretSyncOptionsSection = ({ secretSync, onEditOptions }: Props) =
|
||||
case SecretSync.HCVault:
|
||||
case SecretSync.TeamCity:
|
||||
case SecretSync.OCIVault:
|
||||
case SecretSync.OnePass:
|
||||
AdditionalSyncOptionsComponent = null;
|
||||
break;
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user