fix encryption validation

This commit is contained in:
Ildar Kamalov
2025-02-05 17:52:45 +03:00
parent 6fef2df6b9
commit 8b6d785c72
4 changed files with 74 additions and 55 deletions

8
.gitignore vendored
View File

@@ -19,6 +19,10 @@
/agh-backup/
/bin/
/build/*
/client/blob-report/
/client/playwright-report/
/client/playwright/.cache/
/client/test-results/
/data/
/dist/
/filtering/tests/filtering.TestLotsOfRules*.pprof
@@ -33,9 +37,5 @@ AdGuardHome.exe
AdGuardHome.yaml*
coverage.txt
node_modules/
/client/blob-report/
/client/playwright-report/
/client/playwright/.cache/
/client/test-results/
!/build/gitkeep

View File

@@ -1,4 +1,4 @@
import React, { useEffect, useRef } from 'react';
import React from 'react';
import { Trans, useTranslation } from 'react-i18next';
@@ -92,19 +92,7 @@ export type EncryptionFormValues = {
type Props = {
initialValues: EncryptionFormValues;
processingConfig: boolean;
processingValidate: boolean;
status_key?: string;
not_after?: string;
warning_validation?: string;
valid_chain?: boolean;
valid_key?: boolean;
valid_cert?: boolean;
valid_pair?: boolean;
dns_names?: string[];
key_type?: string;
issuer?: string;
subject?: string;
encryption: EncryptionData;
onSubmit: (values: EncryptionFormValues) => void;
debouncedConfigValidation: (values: EncryptionFormValues) => void;
setTlsConfig: (values: Partial<EncryptionData>) => void;
@@ -130,24 +118,28 @@ const defaultValues = {
export const Form = ({
initialValues,
processingConfig,
processingValidate,
not_after,
valid_chain,
valid_key,
valid_cert,
valid_pair,
dns_names,
key_type,
issuer,
subject,
warning_validation,
encryption,
onSubmit,
setTlsConfig,
debouncedConfigValidation,
validateTlsConfig,
}: Props) => {
const { t } = useTranslation();
const previousValuesRef = useRef<EncryptionFormValues>(initialValues);
const {
not_after,
valid_chain,
valid_key,
valid_cert,
valid_pair,
dns_names,
key_type,
issuer,
subject,
warning_validation,
processingConfig,
processingValidate,
} = encryption;
const {
control,
@@ -166,8 +158,6 @@ export const Form = ({
mode: 'onBlur',
});
const watchedValues = watch();
const {
enabled: isEnabled,
serve_plain_dns: servePlainDns,
@@ -178,16 +168,11 @@ export const Form = ({
private_key_saved: privateKeySaved,
certificate_path: certificatePath,
certificate_source: certificateSource,
} = watchedValues;
} = watch();
useEffect(() => {
const previousValues = previousValuesRef.current;
if (JSON.stringify(previousValues) !== JSON.stringify(watchedValues)) {
// TODO(ik) onChange TLS config validation
previousValuesRef.current = watchedValues;
}
}, [watchedValues]);
const handleBlur = () => {
debouncedConfigValidation(getValues());
};
const isSavingDisabled = () => {
const processing = isSubmitting || processingConfig || processingValidate;
@@ -243,7 +228,9 @@ export const Form = ({
<Controller
name="enabled"
control={control}
render={({ field }) => <Checkbox {...field} title={t('encryption_enable')} />}
render={({ field }) => (
<Checkbox {...field} title={t('encryption_enable')} onBlur={handleBlur} />
)}
/>
</div>
@@ -288,6 +275,7 @@ export const Form = ({
placeholder={t('encryption_server_enter')}
error={fieldState.error?.message}
disabled={!isEnabled}
onBlur={handleBlur}
/>
)}
/>
@@ -337,6 +325,7 @@ export const Form = ({
const { value } = e.target;
field.onChange(toNumber(value));
}}
onBlur={handleBlur}
/>
)}
/>
@@ -368,6 +357,7 @@ export const Form = ({
const { value } = e.target;
field.onChange(toNumber(value));
}}
onBlur={handleBlur}
/>
)}
/>
@@ -399,6 +389,7 @@ export const Form = ({
const { value } = e.target;
field.onChange(toNumber(value));
}}
onBlur={handleBlur}
/>
)}
/>
@@ -457,6 +448,7 @@ export const Form = ({
placeholder={t('encryption_certificates_input')}
disabled={!isEnabled}
error={fieldState.error?.message}
onBlur={handleBlur}
/>
)}
/>
@@ -471,6 +463,7 @@ export const Form = ({
placeholder={t('encryption_certificate_path')}
error={fieldState.error?.message}
disabled={!isEnabled}
onBlur={handleBlur}
/>
)}
/>
@@ -527,6 +520,7 @@ export const Form = ({
}
field.onChange(checked);
}}
onBlur={handleBlur}
/>
)}
/>
@@ -540,6 +534,7 @@ export const Form = ({
placeholder={t('encryption_key_input')}
disabled={!isEnabled || privateKeySaved}
error={fieldState.error?.message}
onBlur={handleBlur}
/>
)}
/>
@@ -555,6 +550,7 @@ export const Form = ({
placeholder={t('encryption_private_key_path')}
error={fieldState.error?.message}
disabled={!isEnabled}
onBlur={handleBlur}
/>
)}
/>

View File

@@ -1,4 +1,4 @@
import React, { useEffect, useCallback, useMemo } from 'react';
import React, { useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { debounce } from 'lodash';
import { DEBOUNCE_TIMEOUT, ENCRYPTION_SOURCE } from '../../../helpers/constants';
@@ -18,19 +18,37 @@ type Props = {
export const Encryption = ({ encryption, setTlsConfig, validateTlsConfig }: Props) => {
const { t } = useTranslation();
useEffect(() => {
if (encryption.enabled) {
validateTlsConfig(encryption);
}
}, [encryption, validateTlsConfig]);
const initialValues = useMemo((): EncryptionFormValues => {
const { certificate_chain, private_key, private_key_saved } = encryption;
const {
enabled,
serve_plain_dns,
server_name,
force_https,
port_https,
port_dns_over_tls,
port_dns_over_quic,
certificate_chain,
private_key,
certificate_path,
private_key_path,
private_key_saved,
} = encryption;
const certificate_source = certificate_chain ? ENCRYPTION_SOURCE.CONTENT : ENCRYPTION_SOURCE.PATH;
const key_source = private_key || private_key_saved ? ENCRYPTION_SOURCE.CONTENT : ENCRYPTION_SOURCE.PATH;
return {
...encryption,
enabled,
serve_plain_dns,
server_name,
force_https,
port_https,
port_dns_over_tls,
port_dns_over_quic,
certificate_chain,
private_key,
certificate_path,
private_key_path,
private_key_saved,
certificate_source,
key_source,
};
@@ -75,7 +93,7 @@ export const Encryption = ({ encryption, setTlsConfig, validateTlsConfig }: Prop
}
}, []);
const debouncedConfigValidation = useCallback(debounce(validateConfig, DEBOUNCE_TIMEOUT), [validateConfig]);
const debouncedConfigValidation = useMemo(() => debounce(validateConfig, DEBOUNCE_TIMEOUT), [validateConfig]);
return (
<div className="encryption">
@@ -94,7 +112,7 @@ export const Encryption = ({ encryption, setTlsConfig, validateTlsConfig }: Prop
debouncedConfigValidation={debouncedConfigValidation}
setTlsConfig={setTlsConfig}
validateTlsConfig={validateTlsConfig}
{...encryption}
encryption={encryption}
/>
</Card>
)}

View File

@@ -12,10 +12,14 @@ type Props = {
className?: string;
error?: string;
onChange: (value: boolean) => void;
onBlur?: () => void;
};
export const Checkbox = forwardRef<HTMLInputElement, Props>(
({ title, subtitle, value, name, disabled, error, className = 'checkbox--form', onChange, ...rest }, ref) => (
(
{ title, subtitle, value, name, disabled, error, className = 'checkbox--form', onChange, onBlur, ...rest },
ref,
) => (
<>
<label className={clsx('checkbox', className)}>
<span className="checkbox__marker" />
@@ -26,6 +30,7 @@ export const Checkbox = forwardRef<HTMLInputElement, Props>(
disabled={disabled}
checked={value}
onChange={(e) => onChange(e.target.checked)}
onBlur={onBlur}
ref={ref}
{...rest}
/>