From b52604045ddb79c2c1457aeacbcb694afdaabe12 Mon Sep 17 00:00:00 2001 From: Maksim Eltyshev Date: Fri, 23 Jan 2026 20:32:23 +0100 Subject: [PATCH] fix: Correctly track password field modification in SMTP pane --- .../common/AdministrationModal/SmtpPane.jsx | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/client/src/components/common/AdministrationModal/SmtpPane.jsx b/client/src/components/common/AdministrationModal/SmtpPane.jsx index 2c0e9260..dcd2bc29 100644 --- a/client/src/components/common/AdministrationModal/SmtpPane.jsx +++ b/client/src/components/common/AdministrationModal/SmtpPane.jsx @@ -4,7 +4,8 @@ */ import { dequal } from 'dequal'; -import React, { useCallback, useMemo } from 'react'; +import omit from 'lodash/omit'; +import React, { useCallback, useMemo, useRef } from 'react'; import classNames from 'classnames'; import { useDispatch, useSelector } from 'react-redux'; import { useTranslation } from 'react-i18next'; @@ -26,6 +27,7 @@ const SmtpPane = React.memo(() => { const [t] = useTranslation(); const [passwordFieldRef, handlePasswordFieldRef] = useNestedRef('inputRef'); + const isPasswordTouchedRef = useRef(false); const defaultData = useMemo( () => ({ @@ -68,7 +70,15 @@ const SmtpPane = React.memo(() => { [data, isPasswordSet], ); + const isModified = useMemo(() => { + const cleanDataToCheck = omit(cleanData, 'smtpPassword'); + const defaultDataToCheck = omit(defaultData, 'smtpPassword'); + + return !dequal(cleanDataToCheck, defaultDataToCheck) || isPasswordTouchedRef.current; + }, [defaultData, cleanData]); + const handleSubmit = useCallback(() => { + isPasswordTouchedRef.current = false; dispatch(entryActions.updateConfig(cleanData)); }, [dispatch, cleanData]); @@ -86,7 +96,13 @@ const SmtpPane = React.memo(() => { dispatch(entryActions.testSmtpConfig()); }, [dispatch]); - const isModified = !dequal(cleanData, defaultData); + const handlePasswordChange = useCallback( + (event, { value, ...props }) => { + isPasswordTouchedRef.current = value !== ''; + handleFieldChange(event, { value, ...props }); + }, + [handleFieldChange], + ); return ( @@ -173,7 +189,7 @@ const SmtpPane = React.memo(() => { maxLength={256} className={styles.field} onClear={!data.smtpPassword && isPasswordSet ? handlePasswordClear : undefined} - onChange={handleFieldChange} + onChange={handlePasswordChange} />
{t('common.defaultFrom')} (