mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-26 20:34:02 +03:00
Fixed validation and edge cases for managed email UI (#19121)
refs GRO-73 - fixed validation for reply-to address - fixed rendering of default values for reply-to and sender-from fields - added a temporary generic message for the verification confirmation, so that it's compatible with both reply-to and from address changes. The message will be improved in a follow-up commit (pending an API change).
This commit is contained in:
parent
8a5e9fb9f6
commit
819ddccc72
@ -52,7 +52,7 @@ const Newsletters: React.FC<{ keywords: string[] }> = ({keywords}) => {
|
|||||||
|
|
||||||
NiceModal.show(ConfirmationModal, {
|
NiceModal.show(ConfirmationModal, {
|
||||||
title: 'Email address verified',
|
title: 'Email address verified',
|
||||||
prompt: <>Success! From address for newsletter <NavigateToNewsletter id={updatedNewsletter.id}>{updatedNewsletter.name}</NavigateToNewsletter> changed to <strong>{updatedNewsletter.sender_email}</strong></>,
|
prompt: <>Success! Email address for newsletter <NavigateToNewsletter id={updatedNewsletter.id}>{updatedNewsletter.name}</NavigateToNewsletter> has been changed.</>,
|
||||||
okLabel: 'Close',
|
okLabel: 'Close',
|
||||||
cancelLabel: '',
|
cancelLabel: '',
|
||||||
onOk: confirmModal => confirmModal?.remove()
|
onOk: confirmModal => confirmModal?.remove()
|
||||||
|
@ -15,12 +15,19 @@ import {getSettingValues} from '@tryghost/admin-x-framework/api/settings';
|
|||||||
import {textColorForBackgroundColor} from '@tryghost/color-utils';
|
import {textColorForBackgroundColor} from '@tryghost/color-utils';
|
||||||
import {useGlobalData} from '../../../providers/GlobalDataProvider';
|
import {useGlobalData} from '../../../providers/GlobalDataProvider';
|
||||||
|
|
||||||
const renderFrom = (newsletter: Newsletter, config: Config, defaultEmailAddress: string|undefined) => {
|
const renderSenderEmail = (newsletter: Newsletter, config: Config, defaultEmailAddress: string|undefined) => {
|
||||||
if (isManagedEmail(config) && defaultEmailAddress) {
|
if (isManagedEmail(config) && !hasSendingDomain(config) && defaultEmailAddress) {
|
||||||
if (!hasSendingDomain(config)) {
|
|
||||||
// Not changeable: sender_email is ignored
|
// Not changeable: sender_email is ignored
|
||||||
return defaultEmailAddress;
|
return defaultEmailAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isManagedEmail(config) && hasSendingDomain(config)) {
|
||||||
|
// Only return sender_email if the domain names match
|
||||||
|
if (newsletter.sender_email?.split('@')[1] === sendingDomain(config)) {
|
||||||
|
return newsletter.sender_email;
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return newsletter.sender_email || defaultEmailAddress || '';
|
return newsletter.sender_email || defaultEmailAddress || '';
|
||||||
@ -32,12 +39,23 @@ const renderReplyToEmail = (newsletter: Newsletter, config: Config, supportEmail
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (newsletter.sender_reply_to === 'newsletter') {
|
if (newsletter.sender_reply_to === 'newsletter') {
|
||||||
return renderFrom(newsletter, config, defaultEmailAddress);
|
return renderSenderEmail(newsletter, config, defaultEmailAddress);
|
||||||
} else if (newsletter.sender_reply_to === 'support') {
|
|
||||||
return supportEmailAddress || defaultEmailAddress || '';
|
|
||||||
} else {
|
|
||||||
return newsletter.sender_reply_to;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (newsletter.sender_reply_to === 'support') {
|
||||||
|
return supportEmailAddress || defaultEmailAddress || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isManagedEmail(config) && hasSendingDomain(config)) {
|
||||||
|
// Only return sender_reply_to if the domain names match
|
||||||
|
if (newsletter.sender_reply_to.split('@')[1] === sendingDomain(config)) {
|
||||||
|
return newsletter.sender_reply_to;
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newsletter.sender_reply_to;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Sidebar: React.FC<{
|
const Sidebar: React.FC<{
|
||||||
@ -59,7 +77,7 @@ const Sidebar: React.FC<{
|
|||||||
const [siteTitle] = getSettingValues(localSettings, ['title']) as string[];
|
const [siteTitle] = getSettingValues(localSettings, ['title']) as string[];
|
||||||
const handleError = useHandleError();
|
const handleError = useHandleError();
|
||||||
|
|
||||||
let newsletterAddress = renderFrom(newsletter, config, defaultEmailAddress);
|
let newsletterAddress = renderSenderEmail(newsletter, config, defaultEmailAddress);
|
||||||
|
|
||||||
const replyToEmails = [
|
const replyToEmails = [
|
||||||
{label: `Newsletter address (${newsletterAddress})`, value: 'newsletter'},
|
{label: `Newsletter address (${newsletterAddress})`, value: 'newsletter'},
|
||||||
@ -137,9 +155,26 @@ const Sidebar: React.FC<{
|
|||||||
};
|
};
|
||||||
|
|
||||||
const renderSenderEmailField = () => {
|
const renderSenderEmailField = () => {
|
||||||
if (isManagedEmail(config)) {
|
// Self-hosters, or legacy Pro users
|
||||||
|
if (!isManagedEmail(config)) {
|
||||||
|
return (
|
||||||
|
<TextField
|
||||||
|
error={Boolean(errors.sender_email)}
|
||||||
|
hint={errors.sender_email}
|
||||||
|
placeholder={newsletterAddress || ''}
|
||||||
|
title="Sender email address"
|
||||||
|
value={newsletter.sender_email || ''}
|
||||||
|
onBlur={validate}
|
||||||
|
onChange={e => updateNewsletter({sender_email: e.target.value})}
|
||||||
|
onKeyDown={() => clearError('sender_email')}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pro users with custom sending domains
|
||||||
if (hasSendingDomain(config)) {
|
if (hasSendingDomain(config)) {
|
||||||
const sendingEmailUsername = newsletter.sender_email?.split('@')[0];
|
const sendingEmail = renderSenderEmail(newsletter, config, defaultEmailAddress);
|
||||||
|
const sendingEmailUsername = sendingEmail?.split('@')[0];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TextField
|
<TextField
|
||||||
@ -157,7 +192,9 @@ const Sidebar: React.FC<{
|
|||||||
onKeyDown={() => clearError('sender_email')}
|
onKeyDown={() => clearError('sender_email')}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
// Pro users without custom sending domains
|
||||||
return (
|
return (
|
||||||
<SettingGroupContent
|
<SettingGroupContent
|
||||||
values={[
|
values={[
|
||||||
@ -170,59 +207,11 @@ const Sidebar: React.FC<{
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<TextField
|
|
||||||
error={Boolean(errors.sender_email)}
|
|
||||||
hint={errors.sender_email}
|
|
||||||
placeholder={newsletterAddress}
|
|
||||||
title="Sender email address"
|
|
||||||
value={newsletter.sender_email || ''}
|
|
||||||
onBlur={validate}
|
|
||||||
onChange={e => updateNewsletter({sender_email: e.target.value})}
|
|
||||||
onKeyDown={() => clearError('sender_email')}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderReplyToEmailField = () => {
|
const renderReplyToEmailField = () => {
|
||||||
if (isManagedEmail(config)) {
|
// Self-hosters, or legacy Pro users
|
||||||
if (hasSendingDomain(config)) {
|
if (!isManagedEmail(config)) {
|
||||||
const replyToEmailUsername = ['newsletter', 'support'].includes(newsletter.sender_reply_to) ? '' : newsletter.sender_reply_to?.split('@')[0];
|
|
||||||
return (
|
|
||||||
<TextField
|
|
||||||
error={Boolean(errors.sender_reply_to)}
|
|
||||||
hint={errors.sender_reply_to}
|
|
||||||
rightPlaceholder={`@${sendingDomain(config)}`}
|
|
||||||
title="Reply-to address"
|
|
||||||
value={replyToEmailUsername || ''}
|
|
||||||
onBlur={validate}
|
|
||||||
onChange={(e) => {
|
|
||||||
const username = e.target.value?.split('@')[0];
|
|
||||||
const newEmail = username ? `${username}@${sendingDomain(config)}` : '';
|
|
||||||
updateNewsletter({sender_reply_to: newEmail});
|
|
||||||
}}
|
|
||||||
onKeyDown={() => clearError('sender_reply_to')}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
<TextField
|
|
||||||
error={Boolean(errors.sender_reply_to)}
|
|
||||||
hint={errors.sender_reply_to}
|
|
||||||
placeholder={newsletterAddress}
|
|
||||||
title="Reply-to email"
|
|
||||||
value={renderReplyToEmail(newsletter, config, supportEmailAddress, defaultEmailAddress)}
|
|
||||||
onBlur={validate}
|
|
||||||
onChange={e => updateNewsletter({sender_reply_to: e.target.value})}
|
|
||||||
onKeyDown={() => clearError('sender_reply_to')}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Select
|
<Select
|
||||||
options={replyToEmails}
|
options={replyToEmails}
|
||||||
@ -231,6 +220,44 @@ const Sidebar: React.FC<{
|
|||||||
onSelect={option => updateNewsletter({sender_reply_to: option?.value})}
|
onSelect={option => updateNewsletter({sender_reply_to: option?.value})}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pro users with custom sending domains
|
||||||
|
if (hasSendingDomain(config)) {
|
||||||
|
const replyToEmail = ['newsletter', 'support'].includes(newsletter.sender_reply_to) ? '' : renderReplyToEmail(newsletter, config, supportEmailAddress, defaultEmailAddress);
|
||||||
|
const replyToEmailUsername = replyToEmail?.split('@')[0] || '';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TextField
|
||||||
|
error={Boolean(errors.sender_reply_to)}
|
||||||
|
hint={errors.sender_reply_to}
|
||||||
|
rightPlaceholder={`@${sendingDomain(config)}`}
|
||||||
|
title="Reply-to address"
|
||||||
|
value={replyToEmailUsername}
|
||||||
|
onBlur={validate}
|
||||||
|
onChange={(e) => {
|
||||||
|
const username = e.target.value?.split('@')[0];
|
||||||
|
const newEmail = username ? `${username}@${sendingDomain(config)}` : 'newsletter';
|
||||||
|
updateNewsletter({sender_reply_to: newEmail});
|
||||||
|
}}
|
||||||
|
onKeyDown={() => clearError('sender_reply_to')}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pro users without custom sending domains
|
||||||
|
return (
|
||||||
|
<TextField
|
||||||
|
error={Boolean(errors.sender_reply_to)}
|
||||||
|
hint={errors.sender_reply_to}
|
||||||
|
placeholder={newsletterAddress || ''}
|
||||||
|
title="Reply-to email"
|
||||||
|
value={renderReplyToEmail(newsletter, config, supportEmailAddress, defaultEmailAddress) || ''}
|
||||||
|
onBlur={validate}
|
||||||
|
onChange={e => updateNewsletter({sender_reply_to: e.target.value})}
|
||||||
|
onKeyDown={() => clearError('sender_reply_to')}
|
||||||
|
/>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const tabs: Tab[] = [
|
const tabs: Tab[] = [
|
||||||
@ -535,7 +562,7 @@ const NewsletterDetailModalContent: React.FC<{newsletter: Newsletter; onlyOne: b
|
|||||||
const {newsletters, meta} = await editNewsletter(formState);
|
const {newsletters, meta} = await editNewsletter(formState);
|
||||||
if (meta?.sent_email_verification) {
|
if (meta?.sent_email_verification) {
|
||||||
if (meta?.sent_email_verification[0] === 'sender_email') {
|
if (meta?.sent_email_verification[0] === 'sender_email') {
|
||||||
const previousFrom = renderFrom(newsletters[0], config, defaultEmailAddress);
|
const previousFrom = renderSenderEmail(newsletters[0], config, defaultEmailAddress);
|
||||||
|
|
||||||
NiceModal.show(ConfirmationModal, {
|
NiceModal.show(ConfirmationModal, {
|
||||||
title: 'Confirm newsletter email address',
|
title: 'Confirm newsletter email address',
|
||||||
@ -584,7 +611,7 @@ const NewsletterDetailModalContent: React.FC<{newsletter: Newsletter; onlyOne: b
|
|||||||
newErrors.sender_email = 'Invalid email.';
|
newErrors.sender_email = 'Invalid email.';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isManagedEmail(config) && formState.sender_reply_to && (!validator.isEmail(formState.sender_reply_to))) {
|
if (formState.sender_reply_to && !validator.isEmail(formState.sender_reply_to) && !['newsletter', 'support'].includes(formState.sender_reply_to)) {
|
||||||
newErrors.sender_reply_to = 'Invalid email.';
|
newErrors.sender_reply_to = 'Invalid email.';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user