Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New sign ups Free email Newsletter notifications has a wrong from email address #17922

Open
1 task done
angelfplaza opened this issue Sep 1, 2023 · 19 comments
Open
1 task done

Comments

@angelfplaza
Copy link

Issue Summary

Explain roughly what’s wrong:
There are a lot of themes that use a non pop up subscribe option and those are the ones that are not working.

The new sign up notification from email address is supposed to be [email protected]. I have already set up all from email address as another address using the smtp config. That email is used for password reset and welcome emails.
To change the newsletter email, that was also sent from the wrong email address.
Even with that wrong, I clicked on the link to replace it and now the newsletter settings shows the right one, but the signups are still being sent from the wrong address.

What did you expect to happen?
Both the email to change the newsletter from address and the new signups for new free subscribers should receive the confirmation email using the SMTP setup email and/or the newsletter one. Not the default [email protected]

Steps to Reproduce

New install.
activate the theme Edition https://github.com/TryGhost/Edition/
go to Settings → Newsletter → Customise- change email- that one will be sent from the wrong email.
Approve that change (if you managed to get the email as I did).

Then confirm that has been changed.
Subscribe to the free emails using a custom embebed form from the theme, not the portal one.
The email is again sent from the wrong one.

Ghost Version

5.60.0

Node.js Version

v18.17.1

How did you install Ghost?

ubuntu 22 following guide and ghost cli

Database type

MySQL 8

Browser & OS version

No response

Relevant log / error output

No response

Code of Conduct

  • I agree to be friendly and polite to people in this repository
@github-actions github-actions bot added the needs:triage [triage] this needs to be triaged by the Ghost team label Sep 1, 2023
@markstos
Copy link
Contributor

markstos commented Sep 4, 2023

The same issue was recently reported on the Ghost forum by a different user and a different version: 5.59.4: https://forum.ghost.org/t/staff-new-sign-ups-email-notifications-has-a-wrong-from-email-address/40671

@markstos
Copy link
Contributor

markstos commented Sep 4, 2023

I can confirm I'm experiencing this issue as well. I just hadn't noticed because email programs don't always display the email address these days, so the issue may be more widespread than is being reported. The earliest message with the issue is August 14th. Unfortunately, I've emptied my trash so I don't have an earlier message where I can confirm the address is set as intended, but I believe it was something other than [email protected] before. Sorry, I don't have the version handy where I ran into the issue-- I've also upgraded since then.

I'm not using Docker and am using Ubuntu 22, installed using the CLI.

@markstos
Copy link
Contributor

markstos commented Sep 4, 2023

I'm able to confirm this is a bug in Ghost. Here's how I isolated and confirmed the issue.

First, I'm aware that the mail structure in config.production.json are all passed directly through to a Nodemailer, so there are some additional options for that module which may not be documented in the Ghost documentation. Importantly, the Nodemailer SMTP transport has both a logger option and a debug option. By enabling both of these, the full the emails generated by Ghost are to the logs where they can be viewed. This way, we can be certain the headers that Ghost includes, vs any modifications that might be made by the SMTP host. In my case, that was Mailgun.

First, I observed that headers are correct for the email that goes to the user to invite them to confirm. This are correct both when Ghost generates them and when I receive them in my inbox. Here's what that looks like in the logs.

Notice the MAIL FROM, the "From:" and the encoded subject line:

 INFO  [vjXc7QXc6k] User "[email protected]" authenticated
 INFO  Sending message <[email protected]> to <[email protected]>
 DEBUG [vjXc7QXc6k] C: MAIL FROM:<[email protected]>
 DEBUG [vjXc7QXc6k] S: 250 Sender address accepted
 DEBUG [vjXc7QXc6k] C: RCPT TO:<[email protected]>
 DEBUG [vjXc7QXc6k] S: 250 Recipient address accepted
 DEBUG [vjXc7QXc6k] C: DATA
 DEBUG [vjXc7QXc6k] S: 354 Continue
 DEBUG [vjXc7QXc6k] Content-Type: multipart/alternative;
 DEBUG [vjXc7QXc6k]  boundary="--_NmP-b9eed4cd15efd278-Part_1"
 DEBUG [vjXc7QXc6k] From: Mark Stosberg <[email protected]>
 DEBUG [vjXc7QXc6k] To: [email protected]
 DEBUG [vjXc7QXc6k] Subject: =?UTF-8?Q?=F0=9F=99=8C_Complete_your_sign_up_to_Ma?=
 DEBUG [vjXc7QXc6k]  =?UTF-8?Q?rk_Stosberg!?=

Now here's the same output for the "New Member Signup" email that goes to admins. Now here, notice the MAIL FROM and "From:" here are different and wrong:

INFO  [5CI2GOGLzfM] User "[email protected]" authenticated
INFO  Sending message <[email protected]> to <[email protected]>
DEBUG [5CI2GOGLzfM] C: MAIL FROM:<[email protected]>
DEBUG [5CI2GOGLzfM] S: 250 Sender address accepted
DEBUG [5CI2GOGLzfM] C: RCPT TO:<[email protected]>
DEBUG [5CI2GOGLzfM] S: 250 Recipient address accepted
DEBUG [5CI2GOGLzfM] C: DATA
DEBUG [5CI2GOGLzfM] S: 354 Continue
DEBUG [5CI2GOGLzfM] Content-Type: multipart/alternative;
DEBUG [5CI2GOGLzfM]  boundary="--_NmP-b3cbe63cea627377-Part_1"
DEBUG [5CI2GOGLzfM] From: Mark Stosberg <[email protected]>
DEBUG [5CI2GOGLzfM] To: [email protected]
DEBUG [5CI2GOGLzfM] Subject: =?UTF-8?Q?=F0=9F=A5=B3_Free_member_signup=3A_Mark_?=
DEBUG [5CI2GOGLzfM]  =?UTF-8?Q?Bikes?=

If there were a problem with a library Ghost was using, I believe they would both be wrong. This finding seems to point to a bug in Ghost itself in how it calls Nodemailer, specifically for the New Member Signup emails.

@markstos
Copy link
Contributor

markstos commented Sep 4, 2023

I tracked this down in the source code to a change made about a year ago by @SimonBackx . It was made to fix a couple product issues which are private, but the title of the commit says "Fixed sending emails from email domain includes 'www subdomain':

#15348

Even before, the email for these appeared to be ghost@${this.siteDomain}. Now the email address used is ghost@${this.defaultEmailDomain}.

The use of ghost@ appears to be specific to emails send from Ghost to staff, but I can see how it could be confusing, as noreply@ is used in other situations and site owners are not expected to have configured the ghost@` address for anything.

To avoid confusion, I recommend further simplifying things by using noreply@ in this case as well.

Here's the specific part of the diff where get fromEmailAddress gets defined:

2e85ae9#diff-16c79093b7a37ab53b6148b7341ee29987bccfc38d9afe12ffd8ce525dc3f564L256

@markstos
Copy link
Contributor

markstos commented Sep 4, 2023

I've submitted a PR with a proposal to use noreply@ in the places where ghost@ is being used. Along with the two other independent bug reporters, the use of ghost@ was confusing to me as well and appeared to be a bug.

@planetahuevo
Copy link

Thank you @markstos for such test and information.
I can also confirm the issue.
To add something more, the issue I think is more related with the part after the @, it is using the wrong domain and not using the emails account specified anywhere on the admin or on the config file.
This is more clear when using a installation of ghost on a subdomain.
The ghost@ or no-reply@ is annoying but does not prevent the emails to reach destination.
The wrong domain after the @ will trigger a lot of spam protections as that subdomain is not expected to send emails and therefore breaking the system (not allowing people to confirm their subscriptions).

@planetahuevo
Copy link

planetahuevo commented Sep 6, 2023

I found this report from 2021:
https://forum.ghost.org/t/emails-to-members-are-failing-user-emails-are-ok/21244
And this one, which is a long one but some comments seems to be related.
https://forum.ghost.org/t/custom-email-configuration-failed-to-send-magic-link-email/38579/34
This has been here for a while it seems.

@TryGhost TryGhost deleted a comment from github-actions bot Oct 13, 2023
@github-actions
Copy link
Contributor

This issue is currently awaiting triage from @daniellockyer. We're having a busy time right now, but we'll update this issue ASAP. If you have any more information to help us triage faster please leave us some comments. Thank you for understanding 🙂

Copy link
Contributor

Our bot has automatically marked this issue as stale because there has not been any activity here in some time.

The issue will be closed soon if there are no further updates, however we ask that you do not post comments to keep the issue open if you are not actively working on a PR.

We keep the issue list minimal so we can keep focus on the most pressing issues. Closed issues can always be reopened if a new contributor is found. Thank you for understanding 🙂

@github-actions github-actions bot added the stale [triage] Issues that were closed to to lack of traction label Feb 10, 2024
@daniellockyer
Copy link
Member

The email sending setup has now changed after #12802 (comment) - please give that a read and let us know if it's still broken 🙂

@daniellockyer daniellockyer closed this as not planned Won't fix, can't repro, duplicate, stale Feb 13, 2024
@github-actions github-actions bot removed the needs:triage [triage] this needs to be triaged by the Ghost team label Feb 13, 2024
@planetahuevo
Copy link

The email sending setup has now changed after #12802 (comment) - please give that a read and let us know if it's still broken 🙂

I will test it, I was aware of the changes.
In any case it should be marked as fixed, not as "not planned" but if you are happy with that I am too... thanks!

@planetahuevo
Copy link

Looks like the issue is still there:
#20381

@markstos
Copy link
Contributor

Here are all the places were noreply is mentioned in the source code:

ghost/core/core/server/services/mail/GhostMailer.js
60:        // Default to noreply@[blog.url]
61:        return getFromAddress(`noreply@${getDomain()}`, requestedReplyToAddress);

ghost/core/core/server/services/newsletters/NewslettersService.js
360:        let fromEmail = `noreply@${toDomain}`;

ghost/core/core/server/services/settings-helpers/SettingsHelpers.js
123:            // In the new flow, we make a difference between an empty setting (= use default) and a 'noreply' setting (=use noreply @ domain)
128:        supportAddress = supportAddress || 'noreply';
130:        // Any fromAddress without domain uses site domain, like default setting `noreply`
171:        return `noreply@${this.getDefaultEmailDomain()}`;

ghost/core/core/server/services/settings/SettingsBREADService.js
358:        if (!email || !hasChanged || email === 'noreply') {
389:        let fromEmail = `noreply@${toDomain}`;

apps/portal/src/utils/helpers.js
732:    const defaultAddress = defaultEmailAddress || `noreply@${getSiteDomain({site})}`;

We can see it's generally used as a default and can be overridden.

I wonder if the OP is running to this edge case in NewslettersService.js:

 async sendEmailVerificationMagicLink({id, email, property = 'sender_from'}) {
        const [,toDomain] = email.split('@');

        let fromEmail = `noreply@${toDomain}`;
        if (fromEmail === email) {
            fromEmail = `no-reply@${toDomain}`;
        }

        if (this.emailAddressService.service.useNewEmailAddresses) {
            // Gone with the old logic: always use the default email address here
            // We don't need to validate the FROM address, only the to address
            // Also because we are not only validating FROM addresses, but also possible REPLY-TO addresses, which we won't send FROM
            fromEmail = this.emailAddressService.service.defaultFromAddress;
        }

That seems to say that if the "From email" is the same as the "To" email, then noreply will be used-- a code comment there would be great to explain why.

But even, it seems that noreply can be overridden useNewEmailAddresses is true.

I'm not clear how useNewEmailAddresses gets set.

@Fmstrat
Copy link

Fmstrat commented Jan 15, 2025

I am experiencing this issue as well, so it is still around. This makes self-hosting unusable since you can't create accounts if your email provider has sender-verification. I.E. Ghost is hosted at https://blog.site.com, so it tries to send the email from [email protected] even though the mail.from is set to [email protected]. Rackspace won't let us send from blog.site.com, only from site.com.

@Fmstrat
Copy link

Fmstrat commented Jan 15, 2025

@markstos The problem is actually here:

let supportAddress = this.settingsCache.get('members_support_address');

On a new setup, members_support_address does not exist. This is especially true in Docker setups because the documentation does not provide an environment variable to configure it: https://ghost.org/docs/config/#mail

You can see on line 126 it then gets set to noreply:

supportAddress = supportAddress || 'noreply';

And then to noreply@sitedomain on 130:

return `${supportAddress}@${this.getDefaultEmailDomain()}`;

No idea why that code is written with multiple statements since it could be significantly cut down.

In any event, forcing that function to return a string of [email protected] (the from address I want for the support address) corrects the issue.

I think an environment variable needs to be configured to support this, and/or it should default to the config item mail.from if it doesn't exist.

EDIT:
It's also possible configuring hostSettings:managedEmail:enabled would work, but I have no idea what that is as it's not documented anywhere. (I'm just glancing at the code, no familiarity with ghost)

@sonmezerekrem
Copy link

I am using 5.108.0. Issue still exist

@MFYDev
Copy link

MFYDev commented Feb 9, 2025

Hey everyone,

I kept receiving email updates on this issue, and today, I finally decided to try it out on my machine. I managed to fix the problem, and in hindsight, the cause was completely my own mistake—something that might seem obvious now, but took me a while to catch.

As I mentioned earlier, I had already set everything in my config.production.json, yet Ghost was still sending emails from noreply. To troubleshoot, I followed the official development guide and ran Ghost from the latest source code: Ghost Install from Source.

I configured the mail.from and SMTP settings properly, then tested local sign-ups, and everything worked perfectly—emails were sent from my own address as expected. This led me to suspect that my production issue was due to an error in my configuration.

Since I was using Docker, I decided to make the change more straightforward by setting mail__from as an environment variable in my docker-compose.yml instead of manually editing mail.from in the config file. After applying this to my production environment, emails were finally sent from the correct sender address.

At this point, I was certain that the issue was with my configuration. After carefully reviewing my settings, I discovered my mistake:

❌ Incorrect configuration (the mistake)

"mail": {
    "transport": "SMTP",
    "options": {
      "service": "Gmail",
      "host": "smtp.gmail.com",
      "port": 465,
      "secure": true,
      "auth": {
        "user": "redacted",
        "pass": "redacted"
      },
    "from":”my email <hi@mydomain>”
    }
  }

The issue?

I accidentally placed "from" under mail.options instead of directly under mail. 🤦

✅ Correct configuration

"mail": {
    "from": "my email <hi@mydomain>",
    "transport": "SMTP",
    "options": {
      "service": "Gmail",
      "host": "smtp.gmail.com",
      "port": 465,
      "secure": true,
      "auth": {
        "user": "redacted",
        "pass": "redacted"
      }
    }
  }

Once I moved "from" to the correct place (mail.from), everything started working properly. I ignored this mainly because ghost put mail.from part https://ghost.org/docs/config/#mail behind other part of the mail config, so that I made this mistake and never found out.

Hopefully, this helps anyone facing the same issue! If this worked for you, let me know. I honestly feel so dumb for missing such a simple mistake… LMFAO. 😅

@Fmstrat
Copy link

Fmstrat commented Feb 10, 2025

@MFYDev Glad you were able to figure this out for yourself! But for any maintainer thinking this issue should be closed:

To troubleshoot, I followed the official development guide and ran Ghost from the latest source code: Ghost Install from Source.

The catch is if you are using a json config instead of the Docker env config, you won't run into this problem. When using the env config, your JSON config would only have this in it:

  "mail": {
    "transport": "Direct"
  },

And your env would be something like:

      mail__transport: SMTP
      mail__from: [email protected]
      mail__options__service: Rackspace
      mail__options__secure: "true"
      mail__options__host: secure.emailsrvr.com
      mail__options__port: 465
      mail__options__auth__user: [email protected]
      mail__options__auth__pass: <redacted>

With this configuration, you hit the issue when you shouldn't, and is what the analysis in #17922 (comment) demonstrates.

@cdzombak
Copy link

Can confirm I'm running into this bug with a new installation of Ghost under Docker.

There appears to be no way to set the From: email address used for sign-up confirmation emails via env variables in the Docker Compose file; the mail__from setting does not apply here.

To work around this, I edited the database directly using hints from the code @Fmstrat discovered:

UPDATE settings SET value='[email protected]' WHERE `key`='members_support_address';

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants