mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-14 20:51:50 +00:00
with stripSchema and filterForSchema
This commit is contained in:
@@ -10,7 +10,8 @@ import {
|
||||
ModalClose,
|
||||
ModalContent,
|
||||
Select,
|
||||
SelectItem
|
||||
SelectItem,
|
||||
Switch
|
||||
} from "@app/components/v2";
|
||||
import { SECRET_SYNC_IMPORT_BEHAVIOR_MAP, SECRET_SYNC_MAP } from "@app/helpers/secretSyncs";
|
||||
import {
|
||||
@@ -31,30 +32,49 @@ type ContentProps = {
|
||||
};
|
||||
|
||||
const FormSchema = z.object({
|
||||
importBehavior: z.nativeEnum(SecretSyncImportBehavior)
|
||||
importBehavior: z.nativeEnum(SecretSyncImportBehavior),
|
||||
filterForSchema: z.boolean(),
|
||||
stripSchema: z.boolean()
|
||||
});
|
||||
|
||||
type TFormData = z.infer<typeof FormSchema>;
|
||||
|
||||
const Content = ({ secretSync, onComplete }: ContentProps) => {
|
||||
const { id: syncId, destination, projectId } = secretSync;
|
||||
const {
|
||||
id: syncId,
|
||||
destination,
|
||||
projectId,
|
||||
syncOptions: { keySchema }
|
||||
} = secretSync;
|
||||
const destinationName = SECRET_SYNC_MAP[destination].name;
|
||||
|
||||
const {
|
||||
handleSubmit,
|
||||
control,
|
||||
formState: { isSubmitting, isDirty }
|
||||
} = useForm<TFormData>({ resolver: zodResolver(FormSchema) });
|
||||
} = useForm<TFormData>({
|
||||
resolver: zodResolver(FormSchema),
|
||||
defaultValues: {
|
||||
filterForSchema: false,
|
||||
stripSchema: false
|
||||
}
|
||||
});
|
||||
|
||||
const triggerImportSecrets = useTriggerSecretSyncImportSecrets();
|
||||
|
||||
const handleTriggerImportSecrets = async ({ importBehavior }: TFormData) => {
|
||||
const handleTriggerImportSecrets = async ({
|
||||
importBehavior,
|
||||
filterForSchema,
|
||||
stripSchema
|
||||
}: TFormData) => {
|
||||
try {
|
||||
await triggerImportSecrets.mutateAsync({
|
||||
syncId,
|
||||
destination,
|
||||
importBehavior,
|
||||
projectId
|
||||
projectId,
|
||||
filterForSchema,
|
||||
stripSchema
|
||||
});
|
||||
|
||||
createNotification({
|
||||
@@ -131,6 +151,64 @@ const Content = ({ secretSync, onComplete }: ContentProps) => {
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
{keySchema && (
|
||||
<>
|
||||
<Controller
|
||||
control={control}
|
||||
name="filterForSchema"
|
||||
defaultValue
|
||||
render={({ field: { value, onChange }, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
tooltipClassName="max-w-md"
|
||||
tooltipText={
|
||||
<div className="flex flex-col gap-2">
|
||||
<p>
|
||||
If enabled, Infisical will only import destination secrets that match your key
|
||||
schema:
|
||||
</p>
|
||||
<code className="text-mineshaft-300">{keySchema}</code>
|
||||
</div>
|
||||
}
|
||||
label="Filter Keys for Schema"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
>
|
||||
<Switch
|
||||
id="filter-for-schema"
|
||||
thumbClassName="bg-mineshaft-800"
|
||||
isChecked={value}
|
||||
onCheckedChange={onChange}
|
||||
>
|
||||
Only import destination secrets that match schema
|
||||
</Switch>
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
control={control}
|
||||
name="stripSchema"
|
||||
defaultValue
|
||||
render={({ field: { value, onChange }, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
tooltipClassName="max-w-md"
|
||||
tooltipText="If enabled, Infisical will strip secret keys according to your schema. Keys that do not match the schema will not be affected."
|
||||
label="Strip Schema"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
>
|
||||
<Switch
|
||||
id="strip-schema"
|
||||
thumbClassName="bg-mineshaft-800"
|
||||
isChecked={value}
|
||||
onCheckedChange={onChange}
|
||||
>
|
||||
Strip schema from imported secret keys
|
||||
</Switch>
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<div className="mt-8 flex w-full items-center justify-between gap-2">
|
||||
<ModalClose asChild>
|
||||
<Button colorSchema="secondary" variant="plain">
|
||||
|
||||
+17
-29
@@ -3,7 +3,7 @@ import { Controller, useFormContext } from "react-hook-form";
|
||||
import { faQuestionCircle, faTriangleExclamation } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
import { FormControl, Select, SelectItem, Switch, Tooltip } from "@app/components/v2";
|
||||
import { FormControl, Input, Select, SelectItem, Switch, Tooltip } from "@app/components/v2";
|
||||
import { SECRET_SYNC_INITIAL_SYNC_BEHAVIOR_MAP, SECRET_SYNC_MAP } from "@app/helpers/secretSyncs";
|
||||
import { SecretSync, useSecretSyncOption } from "@app/hooks/api/secretSyncs";
|
||||
|
||||
@@ -122,6 +122,22 @@ export const SecretSyncOptionsFields = ({ hideInitialSync }: Props) => {
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
<Controller
|
||||
render={({ field: { value, onChange }, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
tooltipClassName="max-w-md"
|
||||
tooltipText="When a secret is synced, it's key will be injected into the key schema before it reaches the destination. This is useful for organization."
|
||||
isError={Boolean(error)}
|
||||
isOptional
|
||||
errorText={error?.message}
|
||||
label="Key Schema"
|
||||
>
|
||||
<Input value={value} onChange={onChange} placeholder="prefix/{{secretKey}}/suffix" />
|
||||
</FormControl>
|
||||
)}
|
||||
control={control}
|
||||
name="syncOptions.keySchema"
|
||||
/>
|
||||
{AdditionalSyncOptionsFieldsComponent}
|
||||
<Controller
|
||||
control={control}
|
||||
@@ -161,34 +177,6 @@ export const SecretSyncOptionsFields = ({ hideInitialSync }: Props) => {
|
||||
);
|
||||
}}
|
||||
/>
|
||||
{/* <Controller
|
||||
render={({ field: { value, onChange }, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
isError={Boolean(error)}
|
||||
isOptional
|
||||
errorText={error?.message}
|
||||
label="Prepend Prefix"
|
||||
>
|
||||
<Input className="uppercase" value={value} onChange={onChange} placeholder="INF_" />
|
||||
</FormControl>
|
||||
)}
|
||||
control={control}
|
||||
name="syncOptions.prependPrefix"
|
||||
/>
|
||||
<Controller
|
||||
render={({ field: { value, onChange }, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
isError={Boolean(error)}
|
||||
isOptional
|
||||
errorText={error?.message}
|
||||
label="Append Suffix"
|
||||
>
|
||||
<Input className="uppercase" value={value} onChange={onChange} placeholder="_INF" />
|
||||
</FormControl>
|
||||
)}
|
||||
control={control}
|
||||
name="syncOptions.appendSuffix"
|
||||
/> */}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
+2
-7
@@ -41,11 +41,7 @@ export const SecretSyncReviewFields = () => {
|
||||
connection,
|
||||
environment,
|
||||
secretPath,
|
||||
syncOptions: {
|
||||
// appendSuffix, prependPrefix,
|
||||
disableSecretDeletion,
|
||||
initialSyncBehavior
|
||||
},
|
||||
syncOptions: { disableSecretDeletion, initialSyncBehavior, keySchema },
|
||||
destination,
|
||||
isAutoSyncEnabled
|
||||
} = watch();
|
||||
@@ -137,8 +133,7 @@ export const SecretSyncReviewFields = () => {
|
||||
<GenericFieldLabel label="Initial Sync Behavior">
|
||||
{SECRET_SYNC_INITIAL_SYNC_BEHAVIOR_MAP[initialSyncBehavior](destinationName).name}
|
||||
</GenericFieldLabel>
|
||||
{/* <SecretSyncLabel label="Prepend Prefix">{prependPrefix}</SecretSyncLabel>
|
||||
<SecretSyncLabel label="Append Suffix">{appendSuffix}</SecretSyncLabel> */}
|
||||
<GenericFieldLabel label="Key Schema">{keySchema}</GenericFieldLabel>
|
||||
{AdditionalSyncOptionsFieldsComponent}
|
||||
{disableSecretDeletion && (
|
||||
<GenericFieldLabel label="Secret Deletion">
|
||||
|
||||
@@ -8,18 +8,17 @@ export const BaseSecretSyncSchema = <T extends AnyZodObject | undefined = undefi
|
||||
) => {
|
||||
const baseSyncOptionsSchema = z.object({
|
||||
initialSyncBehavior: z.nativeEnum(SecretSyncInitialSyncBehavior),
|
||||
disableSecretDeletion: z.boolean().optional().default(false)
|
||||
// scott: removed temporarily for evaluation of template formatting
|
||||
// prependPrefix: z
|
||||
// .string()
|
||||
// .trim()
|
||||
// .transform((str) => str.toUpperCase())
|
||||
// .optional(),
|
||||
// appendSuffix: z
|
||||
// .string()
|
||||
// .trim()
|
||||
// .transform((str) => str.toUpperCase())
|
||||
// .optional()
|
||||
disableSecretDeletion: z.boolean().optional().default(false),
|
||||
keySchema: z
|
||||
.string()
|
||||
.optional()
|
||||
.refine(
|
||||
(val) => !val || /^(?:[a-zA-Z0-9\-/]*)(?:\{\{secretKey\}\})(?:[a-zA-Z0-9\-/]*)$/.test(val),
|
||||
{
|
||||
message:
|
||||
"Key schema must include {{secretKey}} and only contain letters, numbers, dashes, slashes, and the {{secretKey}} placeholder."
|
||||
}
|
||||
)
|
||||
});
|
||||
|
||||
const syncOptionsSchema = additionalSyncOptions
|
||||
|
||||
Reference in New Issue
Block a user