diff --git a/apps/admin-x-settings/src/components/settings/email/newsletters/NewsletterDetailModal.tsx b/apps/admin-x-settings/src/components/settings/email/newsletters/NewsletterDetailModal.tsx index a90fdfd4b3..aefd3c2845 100644 --- a/apps/admin-x-settings/src/components/settings/email/newsletters/NewsletterDetailModal.tsx +++ b/apps/admin-x-settings/src/components/settings/email/newsletters/NewsletterDetailModal.tsx @@ -197,28 +197,15 @@ const Sidebar: React.FC<{ // Pro users with custom sending domains if (hasSendingDomain(config)) { - let sendingEmail = newsletter.sender_email || ''; // Do not use the rendered address here, because this field is editable and we otherwise can't have an empty field - - // It is possible we have an invalid saved email address, in that case it won't get used - // so we should display as if we are using the default = an empty address - if (sendingEmail && sendingEmail !== newsletterAddress) { - sendingEmail = ''; - } - - const sendingEmailUsername = sendingEmail?.split('@')[0] || ''; - return ( { - const username = e.target.value?.split('@')[0]; - const newEmail = username ? `${username}@${sendingDomain(config)}` : ''; - updateNewsletter({sender_email: newEmail}); + updateNewsletter({sender_email: e.target.value}); }} onKeyDown={() => clearError('sender_email')} /> @@ -573,6 +560,8 @@ const NewsletterDetailModalContent: React.FC<{newsletter: Newsletter; onlyOne: b if (formState.sender_email && !validator.isEmail(formState.sender_email)) { newErrors.sender_email = 'Invalid email'; + } else if (formState.sender_email && hasSendingDomain(config) && formState.sender_email.split('@')[1] !== sendingDomain(config)) { + newErrors.sender_email = `Email must end with @${sendingDomain(config)}`; } if (formState.sender_reply_to && !validator.isEmail(formState.sender_reply_to) && !['newsletter', 'support'].includes(formState.sender_reply_to)) { diff --git a/apps/admin-x-settings/src/utils/newsletterEmails.ts b/apps/admin-x-settings/src/utils/newsletterEmails.ts index bb903ad5aa..febad178ed 100644 --- a/apps/admin-x-settings/src/utils/newsletterEmails.ts +++ b/apps/admin-x-settings/src/utils/newsletterEmails.ts @@ -1,4 +1,4 @@ -import {Config, hasSendingDomain, isManagedEmail, sendingDomain} from '@tryghost/admin-x-framework/api/config'; +import {Config, hasSendingDomain, isManagedEmail} from '@tryghost/admin-x-framework/api/config'; import {Newsletter} from '@tryghost/admin-x-framework/api/newsletters'; export const renderSenderEmail = (newsletter: Newsletter, config: Config, defaultEmailAddress: string|undefined) => { @@ -7,15 +7,6 @@ export const renderSenderEmail = (newsletter: Newsletter, config: Config, defaul 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 defaultEmailAddress || ''; - } - } - return newsletter.sender_email || defaultEmailAddress || ''; }; diff --git a/apps/admin-x-settings/test/acceptance/email/newsletters.test.ts b/apps/admin-x-settings/test/acceptance/email/newsletters.test.ts index ead7f535d0..08f5e58539 100644 --- a/apps/admin-x-settings/test/acceptance/email/newsletters.test.ts +++ b/apps/admin-x-settings/test/acceptance/email/newsletters.test.ts @@ -252,7 +252,7 @@ test.describe('Newsletter settings', async () => { }); test.describe('For Ghost (Pro) users with custom sending domain', () => { - test('Allow sender address to be changed partially (username but not domain name)', async ({page}) => { + test('The sender email address can be changed partially (username but not domain name)', async ({page}) => { await mockApi({page, requests: { ...globalDataRequests, browseNewsletters: {method: 'GET', path: '/newsletters/?include=count.active_members%2Ccount.posts&limit=50', response: responseFixtures.newsletters}, @@ -284,11 +284,20 @@ test.describe('Newsletter settings', async () => { const modal = page.getByTestId('newsletter-modal'); const senderEmail = modal.getByLabel('Sender email'); - // The sender email field should keep the username part of the email address - await senderEmail.fill('harry@potter.com'); - expect(await senderEmail.inputValue()).toBe('harry'); + // Error case #1: add invalid email address + await senderEmail.fill('Harry Potter'); + await modal.getByRole('button', {name: 'Save'}).click(); + await expect(page.getByTestId('toast-error').first()).toHaveText(/Can't save newsletter/); + await expect(modal).toHaveText(/Invalid email/); - // The new username is saved without a confirmation popup + // Error case #2: the sender email address doesn't match the custom sending domain + await senderEmail.fill('harry@potter.com'); + await modal.getByRole('button', {name: 'Save'}).click(); + await expect(page.getByTestId('toast-error').first()).toHaveText(/Can't save newsletter/); + await expect(modal).toHaveText(/Email must end with @customdomain.com/); + + // But can have any address on the same domain, without verification + await senderEmail.fill('harry@customdomain.com'); await modal.getByRole('button', {name: 'Save'}).click(); await expect(page.getByTestId('confirmation-modal')).toHaveCount(0); });