mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
remove char and digit rangs and other requested changes/improvments
This commit is contained in:
@@ -1,20 +1,14 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export type PasswordRequirements = {
|
||||
minLength: number;
|
||||
maxLength: number;
|
||||
length: number;
|
||||
required: {
|
||||
lowercase: number;
|
||||
uppercase: number;
|
||||
digits: number;
|
||||
symbols: number;
|
||||
};
|
||||
allowedCharacters?: {
|
||||
lowercase?: string;
|
||||
uppercase?: string;
|
||||
digits?: string;
|
||||
symbols?: string;
|
||||
};
|
||||
allowedSymbols?: string;
|
||||
};
|
||||
|
||||
export enum SqlProviders {
|
||||
@@ -119,23 +113,22 @@ export const DynamicSecretSqlDBSchema = z.object({
|
||||
password: z.string().trim(),
|
||||
passwordRequirements: z
|
||||
.object({
|
||||
minLength: z.number().min(1).max(100),
|
||||
maxLength: z.number().min(1).max(100),
|
||||
length: z.number().min(1).max(250),
|
||||
required: z.object({
|
||||
lowercase: z.number().min(0),
|
||||
uppercase: z.number().min(0),
|
||||
digits: z.number().min(0),
|
||||
symbols: z.number().min(0)
|
||||
}),
|
||||
allowedCharacters: z
|
||||
.object({
|
||||
lowercase: z.string().optional(),
|
||||
uppercase: z.string().optional(),
|
||||
digits: z.string().optional(),
|
||||
symbols: z.string().optional()
|
||||
})
|
||||
.optional()
|
||||
}).refine((data) => {
|
||||
const total = Object.values(data).reduce((sum, count) => sum + count, 0);
|
||||
return total <= 250;
|
||||
}, "Sum of required characters cannot exceed 250"),
|
||||
allowedSymbols: z.string().optional()
|
||||
})
|
||||
.refine((data) => {
|
||||
const total = Object.values(data.required).reduce((sum, count) => sum + count, 0);
|
||||
return total <= data.length;
|
||||
}, "Sum of required characters cannot exceed the total length")
|
||||
.optional()
|
||||
.describe('Password generation requirements'),
|
||||
creationStatement: z.string().trim(),
|
||||
|
||||
@@ -2,6 +2,7 @@ import handlebars from "handlebars";
|
||||
import knex from "knex";
|
||||
import { customAlphabet } from "nanoid";
|
||||
import { z } from "zod";
|
||||
import { randomInt } from 'crypto';
|
||||
|
||||
import { withGatewayProxy } from "@app/lib/gateway";
|
||||
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
||||
@@ -13,26 +14,19 @@ import { DynamicSecretSqlDBSchema, PasswordRequirements, SqlProviders, TDynamicP
|
||||
const EXTERNAL_REQUEST_TIMEOUT = 10 * 1000;
|
||||
|
||||
const DEFAULT_PASSWORD_REQUIREMENTS = {
|
||||
minLength: 48,
|
||||
maxLength: 48,
|
||||
length: 48,
|
||||
required: {
|
||||
lowercase: 1,
|
||||
uppercase: 1,
|
||||
digits: 1,
|
||||
symbols: 0
|
||||
},
|
||||
allowedCharacters: {
|
||||
lowercase: 'abcdefghijklmnopqrstuvwxyz',
|
||||
uppercase: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||
digits: '0123456789',
|
||||
symbols: '-_.~!*'
|
||||
}
|
||||
allowedSymbols: '-_.~!*'
|
||||
};
|
||||
|
||||
const ORACLE_PASSWORD_REQUIREMENTS = {
|
||||
...DEFAULT_PASSWORD_REQUIREMENTS,
|
||||
minLength: 30,
|
||||
maxLength: 30
|
||||
length: 30
|
||||
};
|
||||
|
||||
const generatePassword = (provider: SqlProviders, requirements?: PasswordRequirements) => {
|
||||
@@ -40,52 +34,56 @@ const generatePassword = (provider: SqlProviders, requirements?: PasswordRequire
|
||||
const finalReqs = requirements || defaultReqs;
|
||||
|
||||
try {
|
||||
const { minLength, maxLength, required, allowedCharacters = {} } = finalReqs;
|
||||
const { length, required, allowedSymbols } = finalReqs;
|
||||
|
||||
const chars = {
|
||||
lowercase: allowedCharacters.lowercase || 'abcdefghijklmnopqrstuvwxyz',
|
||||
uppercase: allowedCharacters.uppercase || 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||
digits: allowedCharacters.digits || '0123456789',
|
||||
symbols: allowedCharacters.symbols || '-_.~!*'
|
||||
lowercase: 'abcdefghijklmnopqrstuvwxyz',
|
||||
uppercase: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||
digits: '0123456789',
|
||||
symbols: allowedSymbols || '-_.~!*'
|
||||
};
|
||||
|
||||
const parts: string[] = [];
|
||||
|
||||
if (required.lowercase > 0) {
|
||||
parts.push(...Array(required.lowercase).fill(0).map(() =>
|
||||
chars.lowercase[Math.floor(Math.random() * chars.lowercase.length)]
|
||||
chars.lowercase[randomInt(chars.lowercase.length)]
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
if (required.uppercase > 0) {
|
||||
parts.push(...Array(required.uppercase).fill(0).map(() =>
|
||||
chars.uppercase[Math.floor(Math.random() * chars.uppercase.length)]
|
||||
chars.uppercase[randomInt(chars.uppercase.length)]
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
if (required.digits > 0) {
|
||||
parts.push(...Array(required.digits).fill(0).map(() =>
|
||||
chars.digits[Math.floor(Math.random() * chars.digits.length)]
|
||||
chars.digits[randomInt(chars.digits.length)]
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
if (required.symbols > 0) {
|
||||
parts.push(...Array(required.symbols).fill(0).map(() =>
|
||||
chars.symbols[Math.floor(Math.random() * chars.symbols.length)]
|
||||
chars.symbols[randomInt(chars.symbols.length)]
|
||||
));
|
||||
}
|
||||
|
||||
const requiredTotal = Object.values(required).reduce<number>((a, b) => a + b, 0);
|
||||
const remainingLength = Math.max(minLength - requiredTotal, 0);
|
||||
const remainingLength = Math.max(length - requiredTotal, 0);
|
||||
|
||||
const allowedChars = Object.entries(chars)
|
||||
.filter(([key]) => required[key as keyof typeof required] > 0)
|
||||
.map(([, value]) => value)
|
||||
.join('');
|
||||
|
||||
const allChars = Object.values(chars).join('');
|
||||
parts.push(...Array(remainingLength).fill(0).map(() =>
|
||||
allChars[Math.floor(Math.random() * allChars.length)]
|
||||
allowedChars[randomInt(allowedChars.length)]
|
||||
));
|
||||
|
||||
// shuffle the array to mix up the characters
|
||||
for (let i = parts.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
const j = randomInt(i + 1);
|
||||
[parts[i], parts[j]] = [parts[j], parts[i]];
|
||||
}
|
||||
|
||||
|
||||
@@ -24,23 +24,21 @@ import { gatewaysQueryKeys, useCreateDynamicSecret } from "@app/hooks/api";
|
||||
import { DynamicSecretProviders, SqlProviders } from "@app/hooks/api/dynamicSecret/types";
|
||||
|
||||
const passwordRequirementsSchema = z.object({
|
||||
minLength: z.number().min(1).max(100),
|
||||
maxLength: z.number().min(1).max(100),
|
||||
length: z.number().min(1).max(250),
|
||||
required: z.object({
|
||||
lowercase: z.number().min(0),
|
||||
uppercase: z.number().min(0),
|
||||
digits: z.number().min(0),
|
||||
symbols: z.number().min(0)
|
||||
}),
|
||||
allowedCharacters: z
|
||||
.object({
|
||||
lowercase: z.string().optional(),
|
||||
uppercase: z.string().optional(),
|
||||
digits: z.string().optional(),
|
||||
symbols: z.string().optional()
|
||||
})
|
||||
.optional()
|
||||
});
|
||||
}).refine((data) => {
|
||||
const total = Object.values(data).reduce((sum, count) => sum + count, 0);
|
||||
return total <= 250;
|
||||
}, "Sum of required characters cannot exceed 250"),
|
||||
allowedSymbols: z.string().optional()
|
||||
}).refine((data) => {
|
||||
const total = Object.values(data.required).reduce((sum, count) => sum + count, 0);
|
||||
return total <= data.length;
|
||||
}, "Sum of required characters cannot exceed the total length");
|
||||
|
||||
const formSchema = z.object({
|
||||
provider: z.object({
|
||||
@@ -153,21 +151,22 @@ export const SqlDatabaseInputForm = ({
|
||||
control,
|
||||
setValue,
|
||||
formState: { isSubmitting },
|
||||
handleSubmit
|
||||
handleSubmit,
|
||||
watch
|
||||
} = useForm<TForm>({
|
||||
resolver: zodResolver(formSchema),
|
||||
defaultValues: {
|
||||
provider: {
|
||||
...getSqlStatements(SqlProviders.Postgres),
|
||||
passwordRequirements: {
|
||||
minLength: 48,
|
||||
maxLength: 48,
|
||||
length: 48,
|
||||
required: {
|
||||
lowercase: 1,
|
||||
uppercase: 1,
|
||||
digits: 1,
|
||||
symbols: 0
|
||||
}
|
||||
},
|
||||
allowedSymbols: '-_.~!*'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -208,9 +207,8 @@ export const SqlDatabaseInputForm = ({
|
||||
setValue("provider.port", getDefaultPort(type));
|
||||
|
||||
// Update password requirements based on provider
|
||||
const minMaxLength = type === SqlProviders.Oracle ? 30 : 48;
|
||||
setValue("provider.passwordRequirements.minLength", minMaxLength);
|
||||
setValue("provider.passwordRequirements.maxLength", minMaxLength);
|
||||
const length = type === SqlProviders.Oracle ? 30 : 48;
|
||||
setValue("provider.passwordRequirements.length", length);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -499,41 +497,21 @@ export const SqlDatabaseInputForm = ({
|
||||
Set constraints on the generated database password
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<Controller
|
||||
control={control}
|
||||
name="provider.passwordRequirements.minLength"
|
||||
name="provider.passwordRequirements.length"
|
||||
defaultValue={48}
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Minimum Length"
|
||||
label="Password Length"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
>
|
||||
<Input
|
||||
type="number"
|
||||
min={1}
|
||||
max={100}
|
||||
{...field}
|
||||
onChange={(e) => field.onChange(Number(e.target.value))}
|
||||
/>
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
control={control}
|
||||
name="provider.passwordRequirements.maxLength"
|
||||
defaultValue={48}
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Maximum Length"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
>
|
||||
<Input
|
||||
type="number"
|
||||
min={1}
|
||||
max={100}
|
||||
max={250}
|
||||
{...field}
|
||||
onChange={(e) => field.onChange(Number(e.target.value))}
|
||||
/>
|
||||
@@ -543,7 +521,19 @@ export const SqlDatabaseInputForm = ({
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<h4 className="text-sm font-medium">Required Characters</h4>
|
||||
<h4 className="text-sm font-medium">Minimum Required Character Counts</h4>
|
||||
<div className="text-sm text-gray-500">
|
||||
{(() => {
|
||||
const total = Object.values(watch("provider.passwordRequirements.required") || {}).reduce((sum, count) => sum + Number(count || 0), 0);
|
||||
const length = watch("provider.passwordRequirements.length") || 0;
|
||||
const isError = total > length;
|
||||
return (
|
||||
<span className={isError ? "text-red-500" : ""}>
|
||||
Total required characters: {total} {isError ? `(exceeds length of ${length})` : ""}
|
||||
</span>
|
||||
);
|
||||
})()}
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<Controller
|
||||
control={control}
|
||||
@@ -551,9 +541,10 @@ export const SqlDatabaseInputForm = ({
|
||||
defaultValue={1}
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Lowercase"
|
||||
label="Lowercase Count"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
helperText="Minimum number of lowercase letters"
|
||||
>
|
||||
<Input
|
||||
type="number"
|
||||
@@ -570,9 +561,10 @@ export const SqlDatabaseInputForm = ({
|
||||
defaultValue={1}
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Uppercase"
|
||||
label="Uppercase Count"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
helperText="Minimum number of uppercase letters"
|
||||
>
|
||||
<Input
|
||||
type="number"
|
||||
@@ -589,9 +581,10 @@ export const SqlDatabaseInputForm = ({
|
||||
defaultValue={1}
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Digits"
|
||||
label="Digit Count"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
helperText="Minimum number of digits"
|
||||
>
|
||||
<Input
|
||||
type="number"
|
||||
@@ -608,9 +601,10 @@ export const SqlDatabaseInputForm = ({
|
||||
defaultValue={0}
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Symbols"
|
||||
label="Symbol Count"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
helperText="Minimum number of symbols"
|
||||
>
|
||||
<Input
|
||||
type="number"
|
||||
@@ -625,65 +619,22 @@ export const SqlDatabaseInputForm = ({
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<h4 className="text-sm font-medium">Allowed Characters (Optional)</h4>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<Controller
|
||||
control={control}
|
||||
name="provider.passwordRequirements.allowedCharacters.lowercase"
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Lowercase Characters"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
helperText="Default: a-z"
|
||||
>
|
||||
<Input {...field} placeholder="abcdefghijklmnopqrstuvwxyz" />
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
control={control}
|
||||
name="provider.passwordRequirements.allowedCharacters.uppercase"
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Uppercase Characters"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
helperText="Default: A-Z"
|
||||
>
|
||||
<Input {...field} placeholder="ABCDEFGHIJKLMNOPQRSTUVWXYZ" />
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
control={control}
|
||||
name="provider.passwordRequirements.allowedCharacters.digits"
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Digit Characters"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
helperText="Default: 0-9"
|
||||
>
|
||||
<Input {...field} placeholder="0123456789" />
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
control={control}
|
||||
name="provider.passwordRequirements.allowedCharacters.symbols"
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Symbol Characters"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
helperText="Default: -_.~!*"
|
||||
>
|
||||
<Input {...field} placeholder="-_.~!*" />
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<h4 className="text-sm font-medium">Allowed Symbols</h4>
|
||||
<Controller
|
||||
control={control}
|
||||
name="provider.passwordRequirements.allowedSymbols"
|
||||
defaultValue="-_.~!*"
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Symbols to use in password"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
helperText="Default: -_.~!*"
|
||||
>
|
||||
<Input {...field} placeholder="-_.~!*" />
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</AccordionContent>
|
||||
|
||||
@@ -24,23 +24,21 @@ import { gatewaysQueryKeys, useUpdateDynamicSecret } from "@app/hooks/api";
|
||||
import { SqlProviders, TDynamicSecret } from "@app/hooks/api/dynamicSecret/types";
|
||||
|
||||
const passwordRequirementsSchema = z.object({
|
||||
minLength: z.number().min(1).max(100),
|
||||
maxLength: z.number().min(1).max(100),
|
||||
length: z.number().min(1).max(250),
|
||||
required: z.object({
|
||||
lowercase: z.number().min(0),
|
||||
uppercase: z.number().min(0),
|
||||
digits: z.number().min(0),
|
||||
symbols: z.number().min(0)
|
||||
}),
|
||||
allowedCharacters: z
|
||||
.object({
|
||||
lowercase: z.string().optional(),
|
||||
uppercase: z.string().optional(),
|
||||
digits: z.string().optional(),
|
||||
symbols: z.string().optional()
|
||||
})
|
||||
.optional()
|
||||
});
|
||||
}).refine((data) => {
|
||||
const total = Object.values(data).reduce((sum, count) => sum + count, 0);
|
||||
return total <= 250; // Sanity check for individual validation
|
||||
}, "Sum of required characters cannot exceed 250"),
|
||||
allowedSymbols: z.string().optional()
|
||||
}).refine((data) => {
|
||||
const total = Object.values(data.required).reduce((sum, count) => sum + count, 0);
|
||||
return total <= data.length;
|
||||
}, "Sum of required characters cannot exceed the total length");
|
||||
|
||||
const formSchema = z.object({
|
||||
inputs: z
|
||||
@@ -103,14 +101,14 @@ export const EditDynamicSecretSqlProviderForm = ({
|
||||
projectSlug
|
||||
}: Props) => {
|
||||
const getDefaultPasswordRequirements = (provider: SqlProviders) => ({
|
||||
minLength: provider === SqlProviders.Oracle ? 30 : 48,
|
||||
maxLength: provider === SqlProviders.Oracle ? 30 : 48,
|
||||
length: provider === SqlProviders.Oracle ? 30 : 48,
|
||||
required: {
|
||||
lowercase: 1,
|
||||
uppercase: 1,
|
||||
digits: 1,
|
||||
symbols: 0
|
||||
}
|
||||
},
|
||||
allowedSymbols: '-_.~!*'
|
||||
});
|
||||
|
||||
const {
|
||||
@@ -463,41 +461,21 @@ export const EditDynamicSecretSqlProviderForm = ({
|
||||
Set constraints on the generated database password
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<Controller
|
||||
control={control}
|
||||
name="inputs.passwordRequirements.minLength"
|
||||
name="inputs.passwordRequirements.length"
|
||||
defaultValue={48}
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Minimum Length"
|
||||
label="Password Length"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
>
|
||||
<Input
|
||||
type="number"
|
||||
min={1}
|
||||
max={100}
|
||||
{...field}
|
||||
onChange={(e) => field.onChange(Number(e.target.value))}
|
||||
/>
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
control={control}
|
||||
name="inputs.passwordRequirements.maxLength"
|
||||
defaultValue={48}
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Maximum Length"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
>
|
||||
<Input
|
||||
type="number"
|
||||
min={1}
|
||||
max={100}
|
||||
max={250}
|
||||
{...field}
|
||||
onChange={(e) => field.onChange(Number(e.target.value))}
|
||||
/>
|
||||
@@ -507,7 +485,19 @@ export const EditDynamicSecretSqlProviderForm = ({
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<h4 className="text-sm font-medium">Required Characters</h4>
|
||||
<h4 className="text-sm font-medium">Minimum Required Character Counts</h4>
|
||||
<div className="text-sm text-gray-500">
|
||||
{(() => {
|
||||
const total = Object.values(watch("inputs.passwordRequirements.required") || {}).reduce((sum, count) => sum + Number(count || 0), 0);
|
||||
const length = watch("inputs.passwordRequirements.length") || 0;
|
||||
const isError = total > length;
|
||||
return (
|
||||
<span className={isError ? "text-red-500" : ""}>
|
||||
Total required characters: {total} {isError ? `(exceeds length of ${length})` : ""}
|
||||
</span>
|
||||
);
|
||||
})()}
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<Controller
|
||||
control={control}
|
||||
@@ -515,16 +505,17 @@ export const EditDynamicSecretSqlProviderForm = ({
|
||||
defaultValue={1}
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Lowercase"
|
||||
label="Lowercase Count"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
helperText="Minimum number of lowercase letters"
|
||||
>
|
||||
<Input
|
||||
type="number"
|
||||
min={0}
|
||||
{...field}
|
||||
onChange={(e) => field.onChange(Number(e.target.value))}
|
||||
/>
|
||||
type="number"
|
||||
min={0}
|
||||
{...field}
|
||||
onChange={(e) => field.onChange(Number(e.target.value))}
|
||||
/>
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
@@ -534,16 +525,17 @@ export const EditDynamicSecretSqlProviderForm = ({
|
||||
defaultValue={1}
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Uppercase"
|
||||
label="Uppercase Count"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
helperText="Minimum number of uppercase letters"
|
||||
>
|
||||
<Input
|
||||
type="number"
|
||||
min={0}
|
||||
{...field}
|
||||
onChange={(e) => field.onChange(Number(e.target.value))}
|
||||
/>
|
||||
type="number"
|
||||
min={0}
|
||||
{...field}
|
||||
onChange={(e) => field.onChange(Number(e.target.value))}
|
||||
/>
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
@@ -553,16 +545,17 @@ export const EditDynamicSecretSqlProviderForm = ({
|
||||
defaultValue={1}
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Digits"
|
||||
label="Digit Count"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
helperText="Minimum number of digits"
|
||||
>
|
||||
<Input
|
||||
type="number"
|
||||
min={0}
|
||||
{...field}
|
||||
onChange={(e) => field.onChange(Number(e.target.value))}
|
||||
/>
|
||||
type="number"
|
||||
min={0}
|
||||
{...field}
|
||||
onChange={(e) => field.onChange(Number(e.target.value))}
|
||||
/>
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
@@ -572,16 +565,17 @@ export const EditDynamicSecretSqlProviderForm = ({
|
||||
defaultValue={0}
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Symbols"
|
||||
label="Symbol Count"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
helperText="Minimum number of symbols"
|
||||
>
|
||||
<Input
|
||||
type="number"
|
||||
min={0}
|
||||
{...field}
|
||||
onChange={(e) => field.onChange(Number(e.target.value))}
|
||||
/>
|
||||
type="number"
|
||||
min={0}
|
||||
{...field}
|
||||
onChange={(e) => field.onChange(Number(e.target.value))}
|
||||
/>
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
@@ -589,65 +583,22 @@ export const EditDynamicSecretSqlProviderForm = ({
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<h4 className="text-sm font-medium">Allowed Characters (Optional)</h4>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<Controller
|
||||
control={control}
|
||||
name="inputs.passwordRequirements.allowedCharacters.lowercase"
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Lowercase Characters"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
helperText="Default: a-z"
|
||||
>
|
||||
<Input {...field} placeholder="abcdefghijklmnopqrstuvwxyz" />
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
control={control}
|
||||
name="inputs.passwordRequirements.allowedCharacters.uppercase"
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Uppercase Characters"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
helperText="Default: A-Z"
|
||||
>
|
||||
<Input {...field} placeholder="ABCDEFGHIJKLMNOPQRSTUVWXYZ" />
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
control={control}
|
||||
name="inputs.passwordRequirements.allowedCharacters.digits"
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Digit Characters"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
helperText="Default: 0-9"
|
||||
>
|
||||
<Input {...field} placeholder="0123456789" />
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
control={control}
|
||||
name="inputs.passwordRequirements.allowedCharacters.symbols"
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Symbol Characters"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
helperText="Default: -_.~!*"
|
||||
>
|
||||
<Input {...field} placeholder="-_.~!*" />
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<h4 className="text-sm font-medium">Allowed Symbols</h4>
|
||||
<Controller
|
||||
control={control}
|
||||
name="inputs.passwordRequirements.allowedSymbols"
|
||||
defaultValue="-_.~!*"
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Symbols to use in password"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
helperText="Default: -_.~!*"
|
||||
>
|
||||
<Input {...field} placeholder="-_.~!*" />
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</AccordionContent>
|
||||
|
||||
Reference in New Issue
Block a user