Jump to content

Recommended Posts

Hello

I have a website for a private event organisation where people can signup or contact me using forms. Those forms are sent to me via email. I did not create this forms, a colleague did, since my PHP knowledge is poor.

Currently, I have set up an email account only for sending. The recipients mail address (mine) is definied as global variable in a config file. The senders mail address is set as sender in that email I get for the reason that I easily can reply to that mail and it reaches the sender. And this might be a problem for envelope-to. The senders mail address normally is not part of my email addresses hosted by that provider 🙂

The colleague who made the code for me, used a mail tool called mailHelper which is built up this way:

	<?php
	declare(strict_types=1);
	use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
	class MailHelper
{
	    private PHPMailer $mail;
    private string $ErrorInfo;
	    public function getErrorInfo(): string
    {
        return $this->ErrorInfo;
    }
	    public function hasErrorInfo(): bool
    {
        return !empty($this->ErrorInfo);
    }
	    public function __construct()
    {
        $this->mail = new PHPMailer(true);
        $this->mail->CharSet = PHPMailer::CHARSET_UTF8;
        $this->mail->isHTML(false);
    }
	    /**
     * @throws Exception
     */
    public function toUser(string  $subject,
                           string  $body,
                           string  $to_address,
                           string  $to_name,
                           ?string $from_address = null,
                           ?string $from_name = null): PHPMailer
    {
        if (!$from_address) {
            $from_address = MAIL_FROM_ADDRESS;
        }
	        if (!$from_name) {
            $from_name = MAIL_FROM_NAME;
        }
	        // Validate to address
        if (!filter_var($to_address, FILTER_VALIDATE_EMAIL)) {
            throw new Exception('Invalid to address "'.$to_address.'" for user');
        }
	        // Validate from address
        if (!filter_var($from_address, FILTER_VALIDATE_EMAIL)) {
            throw new Exception('Invalid from address "'.$from_address.'" for user');
        }
	        return $this->handleMail(
            subject: $subject,
            body: $body,
            to_address: $to_address,
            to_name: $to_name,
            from_address: $from_address,
            from_name: $from_name
        );
    }
	    /**
     * @throws Exception
     */
    public function handleMail(string $subject,
                               string $body,
                               string $to_address,
                               string $to_name,
                               string $from_address,
                               string $from_name): PHPMailer
    {
        try {
            /** For SMTP, change the following */
            if (USE_SMTP) {
                $this->mail->isSMTP();
                if (DEBUG) {
                    $this->mail->SMTPDebug = SMTP::DEBUG_SERVER;
                }
                $this->mail->Host = SMTP_HOST;
                $this->mail->SMTPAuth = true;
                $this->mail->Username = SMTP_USERNAME;
                $this->mail->Password = SMTP_PASSWORD;
                $this->mail->SMTPSecure = SMTP_ENCRYPTION;
                $this->mail->Port = SMTP_PORT;
            } else {
                $this->mail->isMail();
            }
	            /** Add the BCC in case there are some given */
            if (count(BCC_RECIPIENTS) > 0) {
                foreach (BCC_RECIPIENTS as $bcc) {
                    // Validate BCC address
                    if (filter_var($bcc, FILTER_VALIDATE_EMAIL)) {
                        $this->mail->addBCC($bcc);
                    }
                }
            }
	            $this->mail->setFrom($from_address, $from_name);
            $this->mail->addAddress($to_address, $to_name);
	            $this->mail->Subject = $subject;
            $this->mail->Body = $body;
	            return $this->mail;
        } catch (Exception $e) {
            $this->ErrorInfo = $e->getMessage();
        }
    }
	    /**
     * @throws Exception
     */
    public function toAdmin(string  $subject,
                            string  $body,
                            ?string $from_address = null,
                            ?string $from_name = null): PHPMailer
    {
        if (!$from_address) {
            $from_address = MAIL_FROM_ADDRESS;
        }
	        if (!$from_name) {
            $from_name = MAIL_FROM_NAME;
        }
	        // Validate to address
        if (!filter_var(MAIL_TO_ADDRESS, FILTER_VALIDATE_EMAIL)) {
            throw new Exception('Invalid to address "'.MAIL_TO_ADDRESS.'" for admin');
        }
	        // Validate from address
        if (!filter_var($from_address, FILTER_VALIDATE_EMAIL)) {
            throw new Exception('Invalid from address "'.$from_address.'" for admin');
        }
	        return $this->handleMail(
            subject: $subject,
            body: $body,
            to_address: MAIL_TO_ADDRESS,
            to_name: MAIL_TO_ADDRESS_NAME,
            from_address: $from_address,
            from_name: $from_name
        );
    }
}

That is the complete MailHelper.php file.

The sending of an email works in this way:

	    $mail = new MailHelper();
	                  $mail->toAdmin(
                    subject: '*subject*',
                    body: $body,      
                    from_address: $inputs['email'],  
                    from_name: $inputs['name']       
                )->send();
	

I hope, you see clear what I am asking for and I hope more that there is a soulution 🙂

Thanks a lot.

It would help if you stated what your problem is.  It's not clear at all, exactly what issue you are having.

In general setting the From address to be someone who filled out a form, is spoofing, and not the way to handle this.   You can not send mail to yourself on behalf of another user, without that looking like you are spoofing.  You also can't "open relay" mail on behalf of others, which is another common mis-configuration issue which will get you blacklisted, and in some cases dropped by your hosting company.  In other words, when you send mail, if you want it to be delivered, you either have to work within what your hosting company allows (which will disallow both spoofing and open relaying) or you need to set up your mail sending so that it neither spoofs nor relays mail.  

Using SMTP (which exists for direct mail server to mail server transfer). The email you are attempting to drop off needs (and ultimately will) come from an email server that will accept it.   The email should come from a fixed legitimate user authorized to send email from your server, and there are many ways for that to happen and potential complexities that are connected to the configuration of your server and hosting.  Your code is attempting to use the SMTP protocol, but it can't send mail directly to another user without having support for all the things that email servers require (SPF, DKIM, DMARC, MX, Valid Reverse DNS entries) if you want to avoid blacklists/and spam or outright rejection of the email.   

Looking at what it appears you are trying to do, I would suggest that you modify things to that you utilize the configured MAIL_FROM_ADDRESS constant, and change the toAdmin method so that it sets the reply to as the user.  You should stop spoofing the from address, for the reasons I already mentioned.  

Unfortunately the poorly written Mailhelper wrapper class is in the way of the PHPMailer class method you need to call which is:

 

$mailhelperObj->addReplyTo($inputs['email', $inputs['name']);

 

The way the MailHelper class is written you would need to alter 

public function handleMail(string $subject,
                               string $body,
                               string $to_address,
                               string $to_name,
                               string $from_address,
                               string $from_name): PHPMailer

And add a new parameter which would probably be "?string $reply_to" -- like so:

 

public function handleMail(string $subject,
                               string $body,
                               string $to_address,
                               string $to_name,
                               string $from_address,
                               string $from_name
                               ?string $reply_to = null
                           ): PHPMailer

Inside the handleEmail method you would want to have something like this:

if ($reply_to) {
    $this->mail->addReplyTo($reply_to, $from_name);
    $from_name = MAIL_FROM_NAME;
}

The reason I'd reset the $from_name here, rather than adding the user provided name, is that I think it's probably a bad idea with any mail client to have the same email address associated with a revolving door of different names, so once the reply to is set, I'd reset it so the actual mail sender did not include the <some name> label, which produces that disconnect.   In other words you don't want an email from "[email protected] <some person>" and then the next time someone uses the contact form, having an email that is "[email protected] <different person>".   When you reply to the person, your email client will use the reply to using their actual email address, which is the reason you were trying to spoof the from email in the first place.  

With these changes as a basis, changing the "toAdmin()" method should be fairly obvious, and I already did more refactoring for a question like this, than I like to do for questions from "non php developers" who just want someone to fix their code for them.  

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.