From b4cf92e843a5bb17ccfc921202c3b9a948cf9948 Mon Sep 17 00:00:00 2001 From: sherryl4george Date: Sun, 17 May 2015 18:52:59 +0530 Subject: [PATCH 01/18] XOAUTH Changes --- class.oauth.php | 49 +++++++++++ class.phpmailer.php | 23 ++++-- class.phpmailer54.php | 163 +++++++++++++++++++++++++++++++++++++ class.smtp.php | 16 +++- composer.json | 58 +++++++------ examples/gmail_xoauth.php | 84 +++++++++++++++++++ examples/gmail_xoauth.phps | 84 +++++++++++++++++++ get_oauth_token.php | 48 +++++++++++ 8 files changed, 491 insertions(+), 34 deletions(-) create mode 100644 class.oauth.php create mode 100644 class.phpmailer54.php create mode 100644 examples/gmail_xoauth.php create mode 100644 examples/gmail_xoauth.phps create mode 100644 get_oauth_token.php diff --git a/class.oauth.php b/class.oauth.php new file mode 100644 index 00000000..3d3df2a6 --- /dev/null +++ b/class.oauth.php @@ -0,0 +1,49 @@ +oauthClientId = $ClientId; + $this->oauthClientSecret = $ClientSecret; + $this->oauthRefreshToken = $RefreshToken; + $this->oauthUserEmail = $UserEmail; + } + + private function getProvider() { + return new League\OAuth2\Client\Provider\Google([ + 'clientId' => $this->oauthClientId, + 'clientSecret' => $this->oauthClientSecret + ]); + } + + private function getGrant(){ + return new \League\OAuth2\Client\Grant\RefreshToken(); + } + + private function getToken(){ + $provider = $this->getProvider(); + $grant = $this->getGrant(); + return $provider->getAccessToken($grant, ['refresh_token' => $this->oauthRefreshToken]); + } + + public function getOauth64(){ + $token = $this->getToken(); + echo $this->oauthUserEmail; + return base64_encode("user=" . $this->oauthUserEmail . "\001auth=Bearer " . $token . "\001\001"); + } + + +} +?> + diff --git a/class.phpmailer.php b/class.phpmailer.php index 09bbd553..a43a3384 100644 --- a/class.phpmailer.php +++ b/class.phpmailer.php @@ -443,7 +443,18 @@ class PHPMailer * @type string */ public $XMailer = ''; - + + /** + * Only For XOAUTH - Google + * Options: An empty string for PHPMailer default, Enter the email used to get access token + * @type string + */ +// public $UserEmail = ''; +// public $RefreshToken = ''; +// public $ClientId = ''; +// public $ClientSecret = ''; + + /** * An instance of the SMTP sender class. * @type SMTP @@ -1317,7 +1328,7 @@ class PHPMailer if (is_null($this->smtp)) { $this->smtp = $this->getSMTPInstance(); } - + // Already connected? if ($this->smtp->connected()) { return true; @@ -1392,10 +1403,10 @@ class PHPMailer } if ($this->SMTPAuth) { if (!$this->smtp->authenticate( - $this->Username, - $this->Password, - $this->AuthType, - $this->Realm, + $this->Username, + $this->Password, + $this->AuthType, + $this->Realm, $this->Workstation ) ) { diff --git a/class.phpmailer54.php b/class.phpmailer54.php new file mode 100644 index 00000000..f771ec33 --- /dev/null +++ b/class.phpmailer54.php @@ -0,0 +1,163 @@ +oauth)) { + $this->oauth = new OAuth($this->oauthUserEmail, + $this->oauthClientSecret, + $this->oauthClientId, + $this->oauthRefreshToken + ); + } + return $this->oauth; + } + + public function smtpConnect($options = array()) + { + if (is_null($this->smtp)) { + $this->smtp = $this->getSMTPInstance(); + } + + if (is_null($this->oauth)) { + $this->oauth = $this->getOAUTHInstance(); + } + + // Already connected? + if ($this->smtp->connected()) { + return true; + } + + $this->smtp->setTimeout($this->Timeout); + $this->smtp->setDebugLevel($this->SMTPDebug); + $this->smtp->setDebugOutput($this->Debugoutput); + $this->smtp->setVerp($this->do_verp); + $hosts = explode(';', $this->Host); + $lastexception = null; + + foreach ($hosts as $hostentry) { + $hostinfo = array(); + if (!preg_match('/^((ssl|tls):\/\/)*([a-zA-Z0-9\.-]*):?([0-9]*)$/', trim($hostentry), $hostinfo)) { + // Not a valid host entry + continue; + } + // $hostinfo[2]: optional ssl or tls prefix + // $hostinfo[3]: the hostname + // $hostinfo[4]: optional port number + // The host string prefix can temporarily override the current setting for SMTPSecure + // If it's not specified, the default value is used + $prefix = ''; + $secure = $this->SMTPSecure; + $tls = ($this->SMTPSecure == 'tls'); + if ('ssl' == $hostinfo[2] or ('' == $hostinfo[2] and 'ssl' == $this->SMTPSecure)) { + $prefix = 'ssl://'; + $tls = false; // Can't have SSL and TLS at the same time + $secure = 'ssl'; + } elseif ($hostinfo[2] == 'tls') { + $tls = true; + // tls doesn't use a prefix + $secure = 'tls'; + } + //Do we need the OpenSSL extension? + $sslext = defined('OPENSSL_ALGO_SHA1'); + if ('tls' === $secure or 'ssl' === $secure) { + //Check for an OpenSSL constant rather than using extension_loaded, which is sometimes disabled + if (!$sslext) { + throw new phpmailerException($this->lang('extension_missing').'openssl', self::STOP_CRITICAL); + } + } + $host = $hostinfo[3]; + $port = $this->Port; + $tport = (integer)$hostinfo[4]; + if ($tport > 0 and $tport < 65536) { + $port = $tport; + } + if ($this->smtp->connect($prefix . $host, $port, $this->Timeout, $options)) { + try { + if ($this->Helo) { + $hello = $this->Helo; + } else { + $hello = $this->serverHostname(); + } + $this->smtp->hello($hello); + //Automatically enable TLS encryption if: + // * it's not disabled + // * we have openssl extension + // * we are not already using SSL + // * the server offers STARTTLS + if ($this->SMTPAutoTLS and $sslext and $secure != 'ssl' and $this->smtp->getServerExt('STARTTLS')) { + $tls = true; + } + if ($tls) { + if (!$this->smtp->startTLS()) { + throw new phpmailerException($this->lang('connect_host')); + } + // We must resend HELO after tls negotiation + $this->smtp->hello($hello); + } + if ($this->SMTPAuth) { + if (!$this->smtp->authenticate( + $this->Username, + $this->Password, + $this->AuthType, + $this->Realm, + $this->Workstation, + $this->oauth + ) + ) { + throw new phpmailerException($this->lang('authenticate')); + } + } + return true; + } catch (phpmailerException $exc) { + $lastexception = $exc; + $this->edebug($exc->getMessage()); + // We must have connected, but then failed TLS or Auth, so close connection nicely + $this->smtp->quit(); + } + } + } + // If we get here, all connection attempts have failed, so close connection hard + $this->smtp->close(); + // As we've caught all exceptions, just report whatever the last one was + if ($this->exceptions and !is_null($lastexception)) { + throw $lastexception; + } + return false; + } + +} + +?> \ No newline at end of file diff --git a/class.smtp.php b/class.smtp.php index b2dfdc18..3d0a525c 100644 --- a/class.smtp.php +++ b/class.smtp.php @@ -364,7 +364,8 @@ class SMTP $password, $authtype = null, $realm = '', - $workstation = '' + $workstation = '', + $OAuth = null ) { if (!$this->server_caps) { $this->setError('Authentication is not allowed before HELO/EHLO'); @@ -436,6 +437,19 @@ class SMTP return false; } break; + case 'XOAUTH': + //If the OAuth Instance is not set. Can be a case when PHPMailer is used + //instead of PHPMailer54 + if(is_null($OAuth)) + return false; + + $oauth = $OAuth->getOauth64(); + + // Start authentication + if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 ' . $oauth, 235)) { + return false; + } + break; case 'NTLM': /* * ntlm_sasl_client.php diff --git a/composer.json b/composer.json index 53d29e8e..2d720596 100644 --- a/composer.json +++ b/composer.json @@ -1,39 +1,43 @@ { - "name": "phpmailer/phpmailer", - "type": "library", - "description": "PHPMailer is a full-featured email creation and transfer class for PHP", - "authors": [ +"name": "phpmailer/phpmailer", + "type": "library", + "description": "PHPMailer is a full-featured email creation and transfer class for PHP", + "authors": [ { - "name": "Marcus Bointon", - "email": "phpmailer@synchromedia.co.uk" + "name": "Marcus Bointon", + "email": "phpmailer@synchromedia.co.uk" }, { - "name": "Jim Jagielski", - "email": "jimjag@gmail.com" + "name": "Jim Jagielski", + "email": "jimjag@gmail.com" }, { - "name": "Andy Prevost", - "email": "codeworxtech@users.sourceforge.net" + "name": "Andy Prevost", + "email": "codeworxtech@users.sourceforge.net" }, { - "name": "Brent R. Matzelle" + "name": "Brent R. Matzelle" } - ], - "require": { - "php": ">=5.0.0" - }, - "require-dev": { + ], + "require": { + "php": ">=5.0.0", + "league/oauth2-client": "0.10.*", + "guzzle/guzzle": "~3.7" + }, + "require-dev": { "phpdocumentor/phpdocumentor": "*", - "phpunit/phpunit": "4.3.*" - }, - "autoload": { + "phpunit/phpunit": "4.3.*" + }, + "autoload": { "classmap": [ - "class.phpmailer.php", - "class.smtp.php", - "class.pop3.php", - "extras/EasyPeasyICS.php", - "extras/ntlm_sasl_client.php" + "class.phpmailer.php", + "class.phpmailer54.php", + "class.oauth.php", + "class.smtp.php", + "class.pop3.php", + "extras/EasyPeasyICS.php", + "extras/ntlm_sasl_client.php" ] - }, - "license": "LGPL-2.1" -} \ No newline at end of file + }, + "license": "LGPL-2.1" + } diff --git a/examples/gmail_xoauth.php b/examples/gmail_xoauth.php new file mode 100644 index 00000000..f6c659e4 --- /dev/null +++ b/examples/gmail_xoauth.php @@ -0,0 +1,84 @@ +isSMTP(); + +//Enable SMTP debugging +// 0 = off (for production use) +// 1 = client messages +// 2 = client and server messages +$mail->SMTPDebug = 2; + +//Ask for HTML-friendly debug output +$mail->Debugoutput = 'html'; + +//Set the hostname of the mail server +$mail->Host = 'smtp.gmail.com'; + +//Set the SMTP port number - 587 for authenticated TLS, a.k.a. RFC4409 SMTP submission +$mail->Port = 587; + +//Set the encryption system to use - ssl (deprecated) or tls +$mail->SMTPSecure = 'tls'; + +//Whether to use SMTP authentication +$mail->SMTPAuth = true; + +//Set AuthTYpe +$mail->AuthType = 'XOAUTH'; + +//UserEmail to use for SMTP authentication - Use the same Email used in Google Developer Console +$mail->oauthUserEmail = "from@example.com"; + +//Obtained From Google Developer Console +$mail->oauthClientId = "RANDOMCHARS----n2.apps.googleusercontent.com"; + +//Obtained From Google Developer Console +$mail->oauthClientSecret = "RANDOMCHARS----yjPcRtvP"; + +//Obtained By running get_oauth_token.php after setting up APP in Google Developer Console. +//Set Redirect URI in Developer Console as [https/http]:////get_oauth_token.php +// eg: http://localhost/phpmail/get_oauth_token.php +$mail->oauthRefreshToken = "RANDOMCHARS----uwFAmhMgMEudVrK5jSpoR30zcRFq6"; + +$mail->setFrom('from@example.com', 'First Last'); + +//Set an alternative reply-to address +$mail->addReplyTo('replyto@example.com', 'First Last'); + +//Set who the message is to be sent to +$mail->addAddress('whoto@example.com', 'John Doe'); + +//Set the subject line +$mail->Subject = 'PHPMailer GMail SMTP test'; + +//Read an HTML message body from an external file, convert referenced images to embedded, +//convert HTML into a basic plain-text alternative body +$mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__)); + +//Replace the plain text body with one created manually +$mail->AltBody = 'This is a plain-text message body'; + +//Attach an image file +$mail->addAttachment('images/phpmailer_mini.png'); + +//send the message, check for errors +if (!$mail->send()) { + echo "Mailer Error: " . $mail->ErrorInfo; +} else { + echo "Message sent!"; +} +?> diff --git a/examples/gmail_xoauth.phps b/examples/gmail_xoauth.phps new file mode 100644 index 00000000..1a2c1e7d --- /dev/null +++ b/examples/gmail_xoauth.phps @@ -0,0 +1,84 @@ +isSMTP(); + +//Enable SMTP debugging +// 0 = off (for production use) +// 1 = client messages +// 2 = client and server messages +$mail->SMTPDebug = 0; + +//Ask for HTML-friendly debug output +$mail->Debugoutput = 'html'; + +//Set the hostname of the mail server +$mail->Host = 'smtp.gmail.com'; + +//Set the SMTP port number - 587 for authenticated TLS, a.k.a. RFC4409 SMTP submission +$mail->Port = 587; + +//Set the encryption system to use - ssl (deprecated) or tls +$mail->SMTPSecure = 'tls'; + +//Whether to use SMTP authentication +$mail->SMTPAuth = true; + +//Set AuthTYpe +$mail->AuthType = 'XOAUTH'; + +//UserEmail to use for SMTP authentication - Use the same Email used in Google Developer Console +$mail->UserEmail = "someone@gmail.com"; + +//Obtained From Google Developer Console +$mail->ClientId = "RANDOMCHARS-----duv1n2.apps.googleusercontent.com"; + +//Obtained From Google Developer Console +$mail->ClientSecret = "RANDOMCHARS-----lGyjPcRtvP"; + +//Obtained By running get_oauth_token.php after setting up APP in Google Developer Console. +//Set Redirect URI in Developer Console as [https/http]:////get_oauth_token.php +// eg: http://localhost/phpmail/get_oauth_token.php +$mail->RefreshToken = "RANDOMCHARS-----DWxgOvPT003r-yFUV49TQYag7_Aod7y0"; + +//Set who the message is to be sent from +$mail->setFrom('from@example.com', 'First Last'); + +//Set an alternative reply-to address +$mail->addReplyTo('replyto@example.com', 'First Last'); + +//Set who the message is to be sent to +$mail->addAddress('whoto@example.com', 'John Doe'); + +//Set the subject line +$mail->Subject = 'PHPMailer GMail SMTP test'; + +//Read an HTML message body from an external file, convert referenced images to embedded, +//convert HTML into a basic plain-text alternative body +$mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__)); + +//Replace the plain text body with one created manually +$mail->AltBody = 'This is a plain-text message body'; + +//Attach an image file +$mail->addAttachment('images/phpmailer_mini.png'); + +//send the message, check for errors +if (!$mail->send()) { + echo "Mailer Error: " . $mail->ErrorInfo; +} else { + echo "Message sent!"; +} +?> \ No newline at end of file diff --git a/get_oauth_token.php b/get_oauth_token.php new file mode 100644 index 00000000..77016808 --- /dev/null +++ b/get_oauth_token.php @@ -0,0 +1,48 @@ +//get_oauth_token.php +// eg: http://localhost/phpmail/get_oauth_token.php +$provider = new League\OAuth2\Client\Provider\Google ([ + 'clientId' => 'RANDOMCHARS----p05gduv1n2.apps.googleusercontent.com', + 'clientSecret' => 'RANDOMCHARS----CWufYlGyjPcRtvP', + 'redirectUri' => $redirectUri, + 'scopes' => ['https://mail.google.com/'], + 'accessType' => 'offline' + ]); + +if (!isset($_GET['code'])) { + + // If we don't have an authorization code then get one + $authUrl = $provider->getAuthorizationUrl(); + $_SESSION['oauth2state'] = $provider->state; + header('Location: ' . $authUrl); + exit; +// Check given state against previously stored one to mitigate CSRF attack +} elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) { + + unset($_SESSION['oauth2state']); + exit('Invalid state'); +} else { + + $provider->accessType = 'offline'; + // Try to get an access token (using the authorization code grant) + $token = $provider->getAccessToken('authorization_code', [ + 'code' => $_GET['code'] + ]); + + +// Use this to interact with an API on the users behalf +// echo $token->accessToken.'
'; + + // Use this to get a new access token if the old one expires + echo 'Refresh Token: '.$token->refreshToken; + +// Unix timestamp of when the token will expire, and need refreshing +// echo $token->expires; +} +?> \ No newline at end of file From e874b2a14b3953dd9d4e97186ce29dd4c309d7c1 Mon Sep 17 00:00:00 2001 From: Synchro Date: Tue, 19 May 2015 17:36:29 +0200 Subject: [PATCH 02/18] Code cleanups --- .gitignore | 1 + ...hpmailer54.php => class.phpmaileroauth.php | 104 ++++++++++++------ class.smtp.php | 20 ++-- composer.json | 56 +++++----- examples/gmail_xoauth.php | 4 +- get_oauth_token.php | 57 ++++++---- 6 files changed, 143 insertions(+), 99 deletions(-) rename class.phpmailer54.php => class.phpmaileroauth.php (69%) diff --git a/.gitignore b/.gitignore index d3c6c62f..e1294abd 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ test/testbootstrap.php test/*.pem .idea build/ +vendor/ diff --git a/class.phpmailer54.php b/class.phpmaileroauth.php similarity index 69% rename from class.phpmailer54.php rename to class.phpmaileroauth.php index f771ec33..25228aac 100644 --- a/class.phpmailer54.php +++ b/class.phpmaileroauth.php @@ -1,50 +1,87 @@ + * @author Jim Jagielski (jimjag) + * @author Andy Prevost (codeworxtech) + * @author Brent R. Matzelle (original founder) + * @copyright 2012 - 2014 Marcus Bointon + * @copyright 2010 - 2012 Jim Jagielski + * @copyright 2004 - 2009 Andy Prevost + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @note This program is distributed in the hope that it will be useful - WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + */ -class PHPMailer54 extends PHPMailer { - +/** + * PHPMailerOAuth - PHPMailer subclass adding OAuth support. + * @package PHPMailer + * @author @sherryl4george + * @author Marcus Bointon (Synchro/coolbru) + */ +class PHPMailerOAuth extends PHPMailer +{ + /** + * The OAuth user's email address + * @type string + */ public $oauthUserEmail = ''; + + /** + * The OAuth refresh token + * @type string + */ public $oauthRefreshToken = ''; + + /** + * The OAuth client ID + * @type string + */ public $oauthClientId = ''; + + /** + * The OAuth client secret + * @type string + */ public $oauthClientSecret = ''; /** - * An instance of the SMTP sender class. - * @type SMTP + * An instance of the OAuth class. + * @type OAuth * @access protected */ protected $oauth = null; - public function __construct() - { - parent::__construct($exceptions = false); - } - /** - * Destructor. - */ - public function __destruct() - { - //Close any open SMTP connection nicely - parent::__destruct(); - } - - /** - * Get an instance to use for SMTP operations. - * Override this function to load your own SMTP implementation - * @return SMTP + * Get an OAuth instance to use. + * @return OAuth */ public function getOAUTHInstance() { if (!is_object($this->oauth)) { - $this->oauth = new OAuth($this->oauthUserEmail, - $this->oauthClientSecret, - $this->oauthClientId, - $this->oauthRefreshToken - ); + $this->oauth = new OAuth( + $this->oauthUserEmail, + $this->oauthClientSecret, + $this->oauthClientId, + $this->oauthRefreshToken + ); } return $this->oauth; } - + + /** + * Initiate a connection to an SMTP server. + * Overrides the original smtpConnect method to add support for OAuth. + * @param array $options An array of options compatible with stream_context_create() + * @uses SMTP + * @access public + * @throws phpmailerException + * @return boolean + */ public function smtpConnect($options = array()) { if (is_null($this->smtp)) { @@ -129,11 +166,11 @@ class PHPMailer54 extends PHPMailer { } if ($this->SMTPAuth) { if (!$this->smtp->authenticate( - $this->Username, - $this->Password, - $this->AuthType, - $this->Realm, - $this->Workstation, + $this->Username, + $this->Password, + $this->AuthType, + $this->Realm, + $this->Workstation, $this->oauth ) ) { @@ -157,7 +194,4 @@ class PHPMailer54 extends PHPMailer { } return false; } - } - -?> \ No newline at end of file diff --git a/class.smtp.php b/class.smtp.php index 3d0a525c..d73a1e6d 100644 --- a/class.smtp.php +++ b/class.smtp.php @@ -351,13 +351,13 @@ class SMTP * Perform SMTP authentication. * Must be run after hello(). * @see hello() - * @param string $username The user name - * @param string $password The password - * @param string $authtype The auth type (PLAIN, LOGIN, NTLM, CRAM-MD5) - * @param string $realm The auth realm for NTLM + * @param string $username The user name + * @param string $password The password + * @param string $authtype The auth type (PLAIN, LOGIN, NTLM, CRAM-MD5) + * @param string $realm The auth realm for NTLM * @param string $workstation The auth workstation for NTLM - * @access public - * @return boolean True if successfully authenticated. + * @param null|OAuth $OAuth An optional OAuth instance (@see PHPMailerOAuth) + * @return bool True if successfully authenticated.* @access public */ public function authenticate( $username, @@ -437,12 +437,12 @@ class SMTP return false; } break; - case 'XOAUTH': + case 'XOAUTH': //If the OAuth Instance is not set. Can be a case when PHPMailer is used - //instead of PHPMailer54 - if(is_null($OAuth)) + //instead of PHPMailerOAuth + if (is_null($OAuth)) { return false; - + } $oauth = $OAuth->getOauth64(); // Start authentication diff --git a/composer.json b/composer.json index 2d720596..59b639ba 100644 --- a/composer.json +++ b/composer.json @@ -1,43 +1,43 @@ { -"name": "phpmailer/phpmailer", - "type": "library", - "description": "PHPMailer is a full-featured email creation and transfer class for PHP", - "authors": [ + "name": "phpmailer/phpmailer", + "type": "library", + "description": "PHPMailer is a full-featured email creation and transfer class for PHP", + "authors": [ { - "name": "Marcus Bointon", - "email": "phpmailer@synchromedia.co.uk" + "name": "Marcus Bointon", + "email": "phpmailer@synchromedia.co.uk" }, { - "name": "Jim Jagielski", - "email": "jimjag@gmail.com" + "name": "Jim Jagielski", + "email": "jimjag@gmail.com" }, { - "name": "Andy Prevost", - "email": "codeworxtech@users.sourceforge.net" + "name": "Andy Prevost", + "email": "codeworxtech@users.sourceforge.net" }, { - "name": "Brent R. Matzelle" + "name": "Brent R. Matzelle" } - ], - "require": { + ], + "require": { "php": ">=5.0.0", "league/oauth2-client": "0.10.*", "guzzle/guzzle": "~3.7" - }, - "require-dev": { + }, + "require-dev": { "phpdocumentor/phpdocumentor": "*", - "phpunit/phpunit": "4.3.*" - }, - "autoload": { + "phpunit/phpunit": "4.3.*" + }, + "autoload": { "classmap": [ - "class.phpmailer.php", - "class.phpmailer54.php", - "class.oauth.php", - "class.smtp.php", - "class.pop3.php", - "extras/EasyPeasyICS.php", - "extras/ntlm_sasl_client.php" + "class.phpmailer.php", + "class.phpmaileroauth.php", + "class.oauth.php", + "class.smtp.php", + "class.pop3.php", + "extras/EasyPeasyICS.php", + "extras/ntlm_sasl_client.php" ] - }, - "license": "LGPL-2.1" - } + }, + "license": "LGPL-2.1" +} diff --git a/examples/gmail_xoauth.php b/examples/gmail_xoauth.php index f6c659e4..967349e9 100644 --- a/examples/gmail_xoauth.php +++ b/examples/gmail_xoauth.php @@ -10,8 +10,8 @@ date_default_timezone_set('Etc/UTC'); require '../PHPMailerAutoload.php'; -//Create a new PHPMailer instance -$mail = new PHPMailer54; +//Create a new PHPMailerOAuth instance +$mail = new PHPMailerOAuth; //Tell PHPMailer to use SMTP $mail->isSMTP(); diff --git a/get_oauth_token.php b/get_oauth_token.php index 77016808..d69d2a55 100644 --- a/get_oauth_token.php +++ b/get_oauth_token.php @@ -1,22 +1,33 @@ //get_oauth_token.php + * e.g.: http://localhost/phpmail/get_oauth_token.php + * * Ensure dependencies are installed with 'composer install' + * * Set up an app in your Google developer console + * * Set the script address as the app's redirect URL + * This script requires PHP 5.4 or later + */ + +require './vendor/autoload.php'; session_start(); -$redirectUri = isset($_SERVER['HTTPS'])?'https://':'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']; +$redirectUri = isset($_SERVER['HTTPS']) ? 'https://' : 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']; //All Details Obtained by setting up APP in Google Developer Console. //Set Redirect URI in Developer Console as [https/http]:////get_oauth_token.php -// eg: http://localhost/phpmail/get_oauth_token.php -$provider = new League\OAuth2\Client\Provider\Google ([ - 'clientId' => 'RANDOMCHARS----p05gduv1n2.apps.googleusercontent.com', - 'clientSecret' => 'RANDOMCHARS----CWufYlGyjPcRtvP', - 'redirectUri' => $redirectUri, - 'scopes' => ['https://mail.google.com/'], - 'accessType' => 'offline' - ]); +$provider = new League\OAuth2\Client\Provider\Google ( + [ + 'clientId' => 'RANDOMCHARS----p05gduv1n2.apps.googleusercontent.com', + 'clientSecret' => 'RANDOMCHARS----CWufYlGyjPcRtvP', + 'redirectUri' => $redirectUri, + 'scopes' => ['https://mail.google.com/'], + 'accessType' => 'offline' + ] +); if (!isset($_GET['code'])) { - // If we don't have an authorization code then get one $authUrl = $provider->getAuthorizationUrl(); $_SESSION['oauth2state'] = $provider->state; @@ -24,25 +35,23 @@ if (!isset($_GET['code'])) { exit; // Check given state against previously stored one to mitigate CSRF attack } elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) { - unset($_SESSION['oauth2state']); exit('Invalid state'); } else { - $provider->accessType = 'offline'; // Try to get an access token (using the authorization code grant) - $token = $provider->getAccessToken('authorization_code', [ - 'code' => $_GET['code'] - ]); - - -// Use this to interact with an API on the users behalf -// echo $token->accessToken.'
'; + $token = $provider->getAccessToken( + 'authorization_code', + [ + 'code' => $_GET['code'] + ] + ); + // Use this to interact with an API on the users behalf + // echo $token->accessToken.'
'; // Use this to get a new access token if the old one expires - echo 'Refresh Token: '.$token->refreshToken; + echo 'Refresh Token: ' . $token->refreshToken; -// Unix timestamp of when the token will expire, and need refreshing -// echo $token->expires; + // Unix timestamp of when the token will expire, and need refreshing + // echo $token->expires; } -?> \ No newline at end of file From 8736a45ae47a2111b78077190bcd3a7cd71d5fc9 Mon Sep 17 00:00:00 2001 From: Synchro Date: Tue, 19 May 2015 17:52:24 +0200 Subject: [PATCH 03/18] Changelog & Readme --- README.md | 6 ++++-- changelog.md | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bb5484ea..de8f354c 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Build status: [![Build Status](https://travis-ci.org/PHPMailer/PHPMailer.svg)](h - Send emails with multiple TOs, CCs, BCCs and REPLY-TOs - Multipart/alternative emails for mail clients that do not read HTML email - Support for UTF-8 content and 8bit, base64, binary, and quoted-printable encodings -- SMTP authentication with LOGIN, PLAIN, NTLM and CRAM-MD5 mechanisms over SSL and TLS transports +- SMTP authentication with LOGIN, PLAIN, NTLM, CRAM-MD5 and Google's XOAUTH2 mechanisms over SSL and TLS transports - Error messages in 47 languages! - DKIM and S/MIME signing support - Compatible with PHP 5.0 and later @@ -48,9 +48,11 @@ If you're not using composer's autoloader, PHPMailer provides an SPL-compatible PHPMailer does *not* declare a namespace because namespaces were only introduced in PHP 5.3. +If you want to use Google's XOAUTH2 authentication mechanism, you need to be running at least PHP 5.4, and load the dependencies listed in `composer.json`. + ### Minimal installation -While installing the entire package manually or with composer is simple, convenient and reliable, you may want to include only vital files in your project. At the very least you will need [class.phpmailer.php](class.phpmailer.php). If you're using SMTP, you'll need [class.smtp.php](class.smtp.php), and if you're using POP-before SMTP, you'll need [class.pop3.php](class.pop3.php). For all of these, we recommend you use [the autoloader](PHPMailerAutoload.php) too as otherwise you will either have to `require` all classes manually or use some other autoloader. You can skip the [language](language/) folder if you're not showing errors to users and can make do with English-only errors. You may need the additional classes in the [extras](extras/) folder if you are using those features, including NTLM authentication and ics generation. +While installing the entire package manually or with composer is simple, convenient and reliable, you may want to include only vital files in your project. At the very least you will need [class.phpmailer.php](class.phpmailer.php). If you're using SMTP, you'll need [class.smtp.php](class.smtp.php), and if you're using POP-before SMTP, you'll need [class.pop3.php](class.pop3.php). For all of these, we recommend you use [the autoloader](PHPMailerAutoload.php) too as otherwise you will either have to `require` all classes manually or use some other autoloader. You can skip the [language](language/) folder if you're not showing errors to users and can make do with English-only errors. You may need the additional classes in the [extras](extras/) folder if you are using those features, including NTLM authentication and ics generation. If you're using Google XOAUTH2 you will need `class.phpmaileroauth.php` and `class.oauth.php` classes too, as well as the composer dependencies. ## A Simple Example diff --git a/changelog.md b/changelog.md index 5ab4690c..14362390 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,7 @@ * Don't switch to quoted-printable for long lines if already using base64 * Fixed Travis-CI config when run on PHP 7 +* Added Google XOAUTH2 authentication mechanism, thanks to @sherryl4george ## Version 5.2.10 (May 4th 2015) * Add custom header getter From ed41c8310d2aa5dc0e405a97dc91c06c20709d4f Mon Sep 17 00:00:00 2001 From: Synchro Date: Wed, 20 May 2015 09:06:40 +0200 Subject: [PATCH 04/18] Docs --- class.smtp.php | 2 +- examples/gmail_xoauth.php | 84 --------------------------------------- get_oauth_token.php | 2 + 3 files changed, 3 insertions(+), 85 deletions(-) delete mode 100644 examples/gmail_xoauth.php diff --git a/class.smtp.php b/class.smtp.php index d73a1e6d..79bd7234 100644 --- a/class.smtp.php +++ b/class.smtp.php @@ -353,7 +353,7 @@ class SMTP * @see hello() * @param string $username The user name * @param string $password The password - * @param string $authtype The auth type (PLAIN, LOGIN, NTLM, CRAM-MD5) + * @param string $authtype The auth type (PLAIN, LOGIN, NTLM, CRAM-MD5, XOAUTH) * @param string $realm The auth realm for NTLM * @param string $workstation The auth workstation for NTLM * @param null|OAuth $OAuth An optional OAuth instance (@see PHPMailerOAuth) diff --git a/examples/gmail_xoauth.php b/examples/gmail_xoauth.php deleted file mode 100644 index 967349e9..00000000 --- a/examples/gmail_xoauth.php +++ /dev/null @@ -1,84 +0,0 @@ -isSMTP(); - -//Enable SMTP debugging -// 0 = off (for production use) -// 1 = client messages -// 2 = client and server messages -$mail->SMTPDebug = 2; - -//Ask for HTML-friendly debug output -$mail->Debugoutput = 'html'; - -//Set the hostname of the mail server -$mail->Host = 'smtp.gmail.com'; - -//Set the SMTP port number - 587 for authenticated TLS, a.k.a. RFC4409 SMTP submission -$mail->Port = 587; - -//Set the encryption system to use - ssl (deprecated) or tls -$mail->SMTPSecure = 'tls'; - -//Whether to use SMTP authentication -$mail->SMTPAuth = true; - -//Set AuthTYpe -$mail->AuthType = 'XOAUTH'; - -//UserEmail to use for SMTP authentication - Use the same Email used in Google Developer Console -$mail->oauthUserEmail = "from@example.com"; - -//Obtained From Google Developer Console -$mail->oauthClientId = "RANDOMCHARS----n2.apps.googleusercontent.com"; - -//Obtained From Google Developer Console -$mail->oauthClientSecret = "RANDOMCHARS----yjPcRtvP"; - -//Obtained By running get_oauth_token.php after setting up APP in Google Developer Console. -//Set Redirect URI in Developer Console as [https/http]:////get_oauth_token.php -// eg: http://localhost/phpmail/get_oauth_token.php -$mail->oauthRefreshToken = "RANDOMCHARS----uwFAmhMgMEudVrK5jSpoR30zcRFq6"; - -$mail->setFrom('from@example.com', 'First Last'); - -//Set an alternative reply-to address -$mail->addReplyTo('replyto@example.com', 'First Last'); - -//Set who the message is to be sent to -$mail->addAddress('whoto@example.com', 'John Doe'); - -//Set the subject line -$mail->Subject = 'PHPMailer GMail SMTP test'; - -//Read an HTML message body from an external file, convert referenced images to embedded, -//convert HTML into a basic plain-text alternative body -$mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__)); - -//Replace the plain text body with one created manually -$mail->AltBody = 'This is a plain-text message body'; - -//Attach an image file -$mail->addAttachment('images/phpmailer_mini.png'); - -//send the message, check for errors -if (!$mail->send()) { - echo "Mailer Error: " . $mail->ErrorInfo; -} else { - echo "Message sent!"; -} -?> diff --git a/get_oauth_token.php b/get_oauth_token.php index d69d2a55..41390f0b 100644 --- a/get_oauth_token.php +++ b/get_oauth_token.php @@ -7,6 +7,8 @@ * * Ensure dependencies are installed with 'composer install' * * Set up an app in your Google developer console * * Set the script address as the app's redirect URL + * If no refresh token is obtained when running this file, revoke access to your app + * using link: https://accounts.google.com/b/0/IssuedAuthSubTokens and run the script again. * This script requires PHP 5.4 or later */ From d24a921e52a81f9b7ed8a97847a8aeaeb12dc39d Mon Sep 17 00:00:00 2001 From: Synchro Date: Thu, 21 May 2015 03:12:17 +0200 Subject: [PATCH 05/18] Changed AuthType name to 'XOAUTH2' Tested, fixed examples Improved token script Code cleanup --- class.oauth.php | 33 +++++++++++++++------------------ class.phpmaileroauth.php | 2 +- class.smtp.php | 6 +++--- examples/gmail_xoauth.phps | 14 ++++++-------- get_oauth_token.php | 13 +++++++++---- 5 files changed, 34 insertions(+), 34 deletions(-) diff --git a/class.oauth.php b/class.oauth.php index 3d3df2a6..69597b3f 100644 --- a/class.oauth.php +++ b/class.oauth.php @@ -1,19 +1,17 @@ oauthClientId = $ClientId; $this->oauthClientSecret = $ClientSecret; $this->oauthRefreshToken = $RefreshToken; @@ -27,23 +25,22 @@ class OAuth { ]); } - private function getGrant(){ + private function getGrant() + { return new \League\OAuth2\Client\Grant\RefreshToken(); } - private function getToken(){ + private function getToken() + { $provider = $this->getProvider(); $grant = $this->getGrant(); return $provider->getAccessToken($grant, ['refresh_token' => $this->oauthRefreshToken]); } - public function getOauth64(){ + public function getOauth64() + { $token = $this->getToken(); echo $this->oauthUserEmail; return base64_encode("user=" . $this->oauthUserEmail . "\001auth=Bearer " . $token . "\001\001"); - } - - + } } -?> - diff --git a/class.phpmaileroauth.php b/class.phpmaileroauth.php index 25228aac..59128313 100644 --- a/class.phpmaileroauth.php +++ b/class.phpmaileroauth.php @@ -21,7 +21,7 @@ * PHPMailerOAuth - PHPMailer subclass adding OAuth support. * @package PHPMailer * @author @sherryl4george - * @author Marcus Bointon (Synchro/coolbru) + * @author Marcus Bointon (@Synchro) */ class PHPMailerOAuth extends PHPMailer { diff --git a/class.smtp.php b/class.smtp.php index 79bd7234..03d624cc 100644 --- a/class.smtp.php +++ b/class.smtp.php @@ -353,7 +353,7 @@ class SMTP * @see hello() * @param string $username The user name * @param string $password The password - * @param string $authtype The auth type (PLAIN, LOGIN, NTLM, CRAM-MD5, XOAUTH) + * @param string $authtype The auth type (PLAIN, LOGIN, NTLM, CRAM-MD5, XOAUTH2) * @param string $realm The auth realm for NTLM * @param string $workstation The auth workstation for NTLM * @param null|OAuth $OAuth An optional OAuth instance (@see PHPMailerOAuth) @@ -389,7 +389,7 @@ class SMTP ); if (empty($authtype)) { - foreach (array('LOGIN', 'CRAM-MD5', 'NTLM', 'PLAIN') as $method) { + foreach (array('LOGIN', 'CRAM-MD5', 'NTLM', 'PLAIN', 'XOAUTH2') as $method) { if (in_array($method, $this->server_caps['AUTH'])) { $authtype = $method; break; @@ -437,7 +437,7 @@ class SMTP return false; } break; - case 'XOAUTH': + case 'XOAUTH2': //If the OAuth Instance is not set. Can be a case when PHPMailer is used //instead of PHPMailerOAuth if (is_null($OAuth)) { diff --git a/examples/gmail_xoauth.phps b/examples/gmail_xoauth.phps index 1a2c1e7d..abef2dd8 100644 --- a/examples/gmail_xoauth.phps +++ b/examples/gmail_xoauth.phps @@ -7,10 +7,11 @@ //This should be done in your php.ini, but this is how to do it if you don't have access to that date_default_timezone_set('Etc/UTC'); -require 'PHPMailerAutoload.php'; +require '../PHPMailerAutoload.php'; +require '../vendor/autoload.php'; //Create a new PHPMailer instance -$mail = new PHPMailer; +$mail = new PHPMailerOAuth; //Tell PHPMailer to use SMTP $mail->isSMTP(); @@ -36,8 +37,8 @@ $mail->SMTPSecure = 'tls'; //Whether to use SMTP authentication $mail->SMTPAuth = true; -//Set AuthTYpe -$mail->AuthType = 'XOAUTH'; +//Set AuthType +$mail->AuthType = 'XOAUTH2'; //UserEmail to use for SMTP authentication - Use the same Email used in Google Developer Console $mail->UserEmail = "someone@gmail.com"; @@ -54,11 +55,9 @@ $mail->ClientSecret = "RANDOMCHARS-----lGyjPcRtvP"; $mail->RefreshToken = "RANDOMCHARS-----DWxgOvPT003r-yFUV49TQYag7_Aod7y0"; //Set who the message is to be sent from +//For gmail, this generally needs to be the same as the user you logged in as $mail->setFrom('from@example.com', 'First Last'); -//Set an alternative reply-to address -$mail->addReplyTo('replyto@example.com', 'First Last'); - //Set who the message is to be sent to $mail->addAddress('whoto@example.com', 'John Doe'); @@ -81,4 +80,3 @@ if (!$mail->send()) { } else { echo "Message sent!"; } -?> \ No newline at end of file diff --git a/get_oauth_token.php b/get_oauth_token.php index 41390f0b..2c4b918d 100644 --- a/get_oauth_token.php +++ b/get_oauth_token.php @@ -12,17 +12,22 @@ * This script requires PHP 5.4 or later */ -require './vendor/autoload.php'; +require 'vendor/autoload.php'; + session_start(); +//If this automatic URL doesn't work, set it yourself manually $redirectUri = isset($_SERVER['HTTPS']) ? 'https://' : 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']; +//$redirectUri = 'http://localhost/phpmailer/get_oauth_token.php'; +$clientId = 'RANDOMCHARS-----duv1n2.apps.googleusercontent.com'; +$clientSecret = 'RANDOMCHARS-----lGyjPcRtvP'; -//All Details Obtained by setting up APP in Google Developer Console. +//All details obtained by setting up app in Google developer console. //Set Redirect URI in Developer Console as [https/http]:////get_oauth_token.php $provider = new League\OAuth2\Client\Provider\Google ( [ - 'clientId' => 'RANDOMCHARS----p05gduv1n2.apps.googleusercontent.com', - 'clientSecret' => 'RANDOMCHARS----CWufYlGyjPcRtvP', + 'clientId' => $clientId, + 'clientSecret' => $clientSecret, 'redirectUri' => $redirectUri, 'scopes' => ['https://mail.google.com/'], 'accessType' => 'offline' From 916ba4b8ac2c91738634a764cb574d4af5b1f368 Mon Sep 17 00:00:00 2001 From: Synchro Date: Wed, 3 Jun 2015 08:48:39 +0200 Subject: [PATCH 06/18] Correct oauth property names --- examples/gmail_xoauth.phps | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/examples/gmail_xoauth.phps b/examples/gmail_xoauth.phps index abef2dd8..4f7d57fc 100644 --- a/examples/gmail_xoauth.phps +++ b/examples/gmail_xoauth.phps @@ -8,6 +8,9 @@ date_default_timezone_set('Etc/UTC'); require '../PHPMailerAutoload.php'; + +//Load dependnecies from composer +//If this causes an error, run 'composer install' require '../vendor/autoload.php'; //Create a new PHPMailer instance @@ -40,19 +43,19 @@ $mail->SMTPAuth = true; //Set AuthType $mail->AuthType = 'XOAUTH2'; -//UserEmail to use for SMTP authentication - Use the same Email used in Google Developer Console -$mail->UserEmail = "someone@gmail.com"; +//User Email to use for SMTP authentication - Use the same Email used in Google Developer Console +$mail->oauthUserEmail = "someone@gmail.com"; //Obtained From Google Developer Console -$mail->ClientId = "RANDOMCHARS-----duv1n2.apps.googleusercontent.com"; +$mail->oauthClientId = "RANDOMCHARS-----duv1n2.apps.googleusercontent.com"; //Obtained From Google Developer Console -$mail->ClientSecret = "RANDOMCHARS-----lGyjPcRtvP"; +$mail->oauthClientSecret = "RANDOMCHARS-----lGyjPcRtvP"; //Obtained By running get_oauth_token.php after setting up APP in Google Developer Console. //Set Redirect URI in Developer Console as [https/http]:////get_oauth_token.php // eg: http://localhost/phpmail/get_oauth_token.php -$mail->RefreshToken = "RANDOMCHARS-----DWxgOvPT003r-yFUV49TQYag7_Aod7y0"; +$mail->oauthRefreshToken = "RANDOMCHARS-----DWxgOvPT003r-yFUV49TQYag7_Aod7y0"; //Set who the message is to be sent from //For gmail, this generally needs to be the same as the user you logged in as From f0e5bf8568abcabb26d441168b6eca52ebe7bd6d Mon Sep 17 00:00:00 2001 From: Synchro Date: Wed, 3 Jun 2015 09:07:34 +0200 Subject: [PATCH 07/18] Don't echo oauthUserEmail --- class.oauth.php | 1 - 1 file changed, 1 deletion(-) diff --git a/class.oauth.php b/class.oauth.php index 69597b3f..1347cc5a 100644 --- a/class.oauth.php +++ b/class.oauth.php @@ -40,7 +40,6 @@ class OAuth public function getOauth64() { $token = $this->getToken(); - echo $this->oauthUserEmail; return base64_encode("user=" . $this->oauthUserEmail . "\001auth=Bearer " . $token . "\001\001"); } } From 552a0c6930b061e55ec7f95dec6fd720512a36cb Mon Sep 17 00:00:00 2001 From: Merijn Date: Mon, 29 Jun 2015 15:57:38 +0200 Subject: [PATCH 08/18] do not auto-replace inline images in body that are already replaced --- class.phpmailer.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/class.phpmailer.php b/class.phpmailer.php index a92d16d3..094add6c 100644 --- a/class.phpmailer.php +++ b/class.phpmailer.php @@ -3108,8 +3108,9 @@ class PHPMailer $message ); } - } elseif (!preg_match('#^[A-z]+://#', $url)) { + } elseif (!preg_match('#^[A-z]+://#', $url) && !preg_match('#^cid:#', $url)) { // Do not change urls for absolute images (thanks to corvuscorax) + // Do not change urls that are already inline images $filename = basename($url); $directory = dirname($url); if ($directory == '.') { From 2722cc148b2a0023a24566c3f9814b2fb096a0fd Mon Sep 17 00:00:00 2001 From: Merijn Date: Mon, 29 Jun 2015 17:02:13 +0200 Subject: [PATCH 09/18] amend last commit --- class.phpmailer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/class.phpmailer.php b/class.phpmailer.php index 094add6c..f6cfe709 100644 --- a/class.phpmailer.php +++ b/class.phpmailer.php @@ -3108,7 +3108,7 @@ class PHPMailer $message ); } - } elseif (!preg_match('#^[A-z]+://#', $url) && !preg_match('#^cid:#', $url)) { + } elseif (!preg_match('#^[A-z]+://#', $url) && substr($url, 0, 4) !== 'cid') { // Do not change urls for absolute images (thanks to corvuscorax) // Do not change urls that are already inline images $filename = basename($url); From a54c92cf2591b3cc1526d88c6928c2e43e05f331 Mon Sep 17 00:00:00 2001 From: Merijn Date: Tue, 30 Jun 2015 08:26:43 +0200 Subject: [PATCH 10/18] fixed typo, condition order --- class.phpmailer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/class.phpmailer.php b/class.phpmailer.php index f6cfe709..e3717535 100644 --- a/class.phpmailer.php +++ b/class.phpmailer.php @@ -3108,7 +3108,7 @@ class PHPMailer $message ); } - } elseif (!preg_match('#^[A-z]+://#', $url) && substr($url, 0, 4) !== 'cid') { + } elseif (substr($url, 0, 4) !== 'cid:' && !preg_match('#^[A-z]+://#', $url)) { // Do not change urls for absolute images (thanks to corvuscorax) // Do not change urls that are already inline images $filename = basename($url); From a378ec789503e69ffa91c23757ca3b733ee75769 Mon Sep 17 00:00:00 2001 From: Rodrigo Prado Date: Tue, 14 Jul 2015 10:02:37 -0300 Subject: [PATCH 11/18] addex how to install with composer --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 2b36eb18..4771cb75 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,12 @@ PHPMailer is available via [Composer/Packagist](https://packagist.org/packages/p "phpmailer/phpmailer": "~5.2" +or use the command below: + +```sh +composer require phpmailer/phpmailer +``` + Alternatively, copy the contents of the PHPMailer folder into somewhere that's in your PHP `include_path` setting. If you don't speak git or just want a tarball, click the 'zip' button at the top of the page in GitHub. If you're not using composer's autoloader, PHPMailer provides an SPL-compatible autoloader, and that is the preferred way of loading the library - just `require '/path/to/PHPMailerAutoload.php';` and everything should work. The autoloader does not throw errors if it can't find classes so it prepends itself to the SPL list, allowing your own (or your framework's) autoloader to catch errors. SPL autoloading was introduced in PHP 5.1.0, so if you are using a version older than that you will need to require/include each class manually. From b8fdec8fd586b7847f9575cb0848102d0f2747c2 Mon Sep 17 00:00:00 2001 From: Wolfgang Jentner Date: Sat, 22 Aug 2015 22:59:51 +0200 Subject: [PATCH 12/18] Added an example file explaining how to send signed emails --- examples/signed-mail.phps | 82 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 examples/signed-mail.phps diff --git a/examples/signed-mail.phps b/examples/signed-mail.phps new file mode 100644 index 00000000..a9c3140a --- /dev/null +++ b/examples/signed-mail.phps @@ -0,0 +1,82 @@ +setFrom('from@example.com', 'First Last'); +//Set an alternative reply-to address +$mail->addReplyTo('replyto@example.com', 'First Last'); +//Set who the message is to be sent to +$mail->addAddress('whoto@example.com', 'John Doe'); +//Set the subject line +$mail->Subject = 'PHPMailer mail() test'; +//Read an HTML message body from an external file, convert referenced images to embedded, +//convert HTML into a basic plain-text alternative body +$mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__)); +//Replace the plain text body with one created manually +$mail->AltBody = 'This is a plain-text message body'; +//Attach an image file +$mail->addAttachment('images/phpmailer_mini.png'); + +//signing the email +$mail->sign('/path/to/cert.crt', //the location of your certificate file + '/path/to/cert.key', //the location of your private key file + 'yourSecretPrivateKeyPassword'); //the password you protected your private key with (may be empty but parameter can not mit omitted!) + //!!!! This is not the Import Password !!!! + +//send the message, check for errors +if (!$mail->send()) { + echo "Mailer Error: " . $mail->ErrorInfo; +} else { + echo "Message sent!"; +} + +/** + * REMARKS: + * If your email client does not support S/MIME it will most likely just show an attachment smime.p7s which is the signature contained in the email. + * Other clients, such as Thunderbird support S/MIME natively and will validate the signature automatically and report the result in some way. + */ +?> \ No newline at end of file From c93759dcd19b43a1fb905dc83dec51d1287b24bc Mon Sep 17 00:00:00 2001 From: Synchro Date: Tue, 25 Aug 2015 12:01:39 +0200 Subject: [PATCH 13/18] Fix issues with embedding items without filenames, fixes #478 --- class.phpmailer.php | 45 +++++++++++++++++++++++++++++------------- test/phpmailerTest.php | 25 +++++++++++++++++++++++ 2 files changed, 56 insertions(+), 14 deletions(-) diff --git a/class.phpmailer.php b/class.phpmailer.php index 34c2ea1d..94a50a9d 100644 --- a/class.phpmailer.php +++ b/class.phpmailer.php @@ -2330,12 +2330,21 @@ class PHPMailer $cidUniq[$cid] = true; $mime[] = sprintf('--%s%s', $boundary, $this->LE); - $mime[] = sprintf( - 'Content-Type: %s; name="%s"%s', - $type, - $this->encodeHeader($this->secureHeader($name)), - $this->LE - ); + //Only include a filename property if we have one + if (!empty($name)) { + $mime[] = sprintf( + 'Content-Type: %s; name="%s"%s', + $type, + $this->encodeHeader($this->secureHeader($name)), + $this->LE + ); + } else { + $mime[] = sprintf( + 'Content-Type: %s%s', + $type, + $this->LE + ); + } // RFC1341 part 5 says 7bit is assumed if not specified if ($encoding != '7bit') { $mime[] = sprintf('Content-Transfer-Encoding: %s%s', $encoding, $this->LE); @@ -2359,12 +2368,20 @@ class PHPMailer $this->LE . $this->LE ); } else { - $mime[] = sprintf( - 'Content-Disposition: %s; filename=%s%s', - $disposition, - $encoded_name, - $this->LE . $this->LE - ); + if (!empty($encoded_name)) { + $mime[] = sprintf( + 'Content-Disposition: %s; filename=%s%s', + $disposition, + $encoded_name, + $this->LE . $this->LE + ); + } else { + $mime[] = sprintf( + 'Content-Disposition: %s%s', + $disposition, + $this->LE . $this->LE + ); + } } } else { $mime[] = $this->LE; @@ -2801,7 +2818,7 @@ class PHPMailer $disposition = 'inline' ) { // If a MIME type is not specified, try to work it out from the name - if ($type == '') { + if ($type == '' and !empty($name)) { $type = self::filenameToType($name); } @@ -3103,7 +3120,7 @@ class PHPMailer $data = rawurldecode($data); } $cid = md5($url) . '@phpmailer.0'; // RFC2392 S 2 - if ($this->addStringEmbeddedImage($data, $cid, '', 'base64', $match[1])) { + if ($this->addStringEmbeddedImage($data, $cid, 'embed' . $imgindex, 'base64', $match[1])) { $message = str_replace( $images[0][$imgindex], $images[1][$imgindex] . '="cid:' . $cid . '"', diff --git a/test/phpmailerTest.php b/test/phpmailerTest.php index 711e9c3e..4d9153a3 100644 --- a/test/phpmailerTest.php +++ b/test/phpmailerTest.php @@ -975,6 +975,31 @@ EOT; $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo); } + /** + * Test embedded image without a name + */ + public function testHTMLStringEmbedNoName() + { + $this->Mail->Body = 'This is the HTML part of the email.'; + $this->Mail->Subject .= ': HTML + unnamed embedded image'; + $this->Mail->isHTML(true); + + if (!$this->Mail->addStringEmbeddedImage( + file_get_contents('../examples/images/phpmailer_mini.png'), + md5('phpmailer_mini.png').'@phpmailer.0', + '', //intentionally empty name + 'base64', + 'image/png', + 'inline') + ) { + $this->assertTrue(false, $this->Mail->ErrorInfo); + return; + } + + $this->buildBody(); + $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo); + } + /** * Simple HTML and multiple attachment test */ From 58a6a5cf1453789deff2ce74d2f1f90b7696d156 Mon Sep 17 00:00:00 2001 From: Synchro Date: Tue, 25 Aug 2015 12:06:47 +0200 Subject: [PATCH 14/18] Changelog --- changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.md b/changelog.md index 25632672..129d47d7 100644 --- a/changelog.md +++ b/changelog.md @@ -6,6 +6,7 @@ * Update MS Office MIME types * Don't convert line breaks when using quoted-printable encoding * Handle MS Exchange returning an invalid empty AUTH-type list in EHLO +* Don't set name or filename properties on MIME parts that don't have one ## Version 5.2.10 (May 4th 2015) * Add custom header getter From 7830cb9a761d974e58e3173137eac93da1cd715a Mon Sep 17 00:00:00 2001 From: Synchro Date: Mon, 31 Aug 2015 12:37:13 +0200 Subject: [PATCH 15/18] Bump version to 5.2.11 --- VERSION | 2 +- changelog.md | 1 + class.phpmailer.php | 2 +- class.pop3.php | 2 +- class.smtp.php | 4 ++-- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/VERSION b/VERSION index b4e08793..7ef7e8d8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -5.2.10 \ No newline at end of file +5.2.11 \ No newline at end of file diff --git a/changelog.md b/changelog.md index 31155e0f..90c3a96b 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,6 @@ # ChangeLog +## Version 5.2.11 (Aug 31st 2015) * Don't switch to quoted-printable for long lines if already using base64 * Fixed Travis-CI config when run on PHP 7 * Added Google XOAUTH2 authentication mechanism, thanks to @sherryl4george diff --git a/class.phpmailer.php b/class.phpmailer.php index 93398b21..6816798e 100644 --- a/class.phpmailer.php +++ b/class.phpmailer.php @@ -31,7 +31,7 @@ class PHPMailer * The PHPMailer Version number. * @type string */ - public $Version = '5.2.10'; + public $Version = '5.2.11'; /** * Email priority. diff --git a/class.pop3.php b/class.pop3.php index f63619c3..d6d9b374 100644 --- a/class.pop3.php +++ b/class.pop3.php @@ -34,7 +34,7 @@ class POP3 * @type string * @access public */ - public $Version = '5.2.10'; + public $Version = '5.2.11'; /** * Default POP3 port number. diff --git a/class.smtp.php b/class.smtp.php index ff557a20..055dc1ff 100644 --- a/class.smtp.php +++ b/class.smtp.php @@ -30,7 +30,7 @@ class SMTP * The PHPMailer SMTP version number. * @type string */ - const VERSION = '5.2.10'; + const VERSION = '5.2.11'; /** * SMTP line break constant. @@ -81,7 +81,7 @@ class SMTP * @deprecated Use the `VERSION` constant instead * @see SMTP::VERSION */ - public $Version = '5.2.10'; + public $Version = '5.2.11'; /** * SMTP server port number. From 126ffa991f073ddf34cfd906c81937ee6cf02996 Mon Sep 17 00:00:00 2001 From: Frederik Bosch Date: Wed, 2 Sep 2015 12:01:43 +0200 Subject: [PATCH 16/18] Do no require a dependency that is not required First of all, do not require dependencies that are not required for PHPMailer to work. It works perfectly without. Secondly, the majority of the users will not use Gmail's XOAUTH2 authentication system and do not need these additional dependencies. Thirdly, guzzle and league packages are used a lot. Therefore you make it hard for people that were already using these packages to newer versions of PHPMailer. --- composer.json | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 59b639ba..05f74bae 100644 --- a/composer.json +++ b/composer.json @@ -20,14 +20,16 @@ } ], "require": { - "php": ">=5.0.0", - "league/oauth2-client": "0.10.*", - "guzzle/guzzle": "~3.7" + "php": ">=5.0.0" }, "require-dev": { "phpdocumentor/phpdocumentor": "*", "phpunit/phpunit": "4.3.*" }, + "suggest": { + "league/oauth2-client": "0.10.*", + "guzzle/guzzle": "~3.7" + }, "autoload": { "classmap": [ "class.phpmailer.php", From df582f0a568673e58407b76856f64077a2a1dc7f Mon Sep 17 00:00:00 2001 From: Frederik Bosch Date: Wed, 2 Sep 2015 12:21:21 +0200 Subject: [PATCH 17/18] Remove guzzle, suggest oauth2 --- composer.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 05f74bae..d68d45cb 100644 --- a/composer.json +++ b/composer.json @@ -27,8 +27,7 @@ "phpunit/phpunit": "4.3.*" }, "suggest": { - "league/oauth2-client": "0.10.*", - "guzzle/guzzle": "~3.7" + "league/oauth2-client": "Needed for Gmail's XOAUTH2 authentication system" }, "autoload": { "classmap": [ From 5dd754112d07ab7480824c2916689ce06f83a842 Mon Sep 17 00:00:00 2001 From: Synchro Date: Wed, 2 Sep 2015 12:40:37 +0200 Subject: [PATCH 18/18] 5.2.12 release --- README.md | 6 +----- VERSION | 2 +- changelog.md | 4 ++++ class.phpmailer.php | 2 +- class.pop3.php | 2 +- class.smtp.php | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 4307fd34..4bfefa18 100644 --- a/README.md +++ b/README.md @@ -50,11 +50,7 @@ or composer require phpmailer/phpmailer ``` -or use the command below: - -```sh -composer require phpmailer/phpmailer -``` +If you want to use the Gmail XOAUTH2 authentication class, you will also need to add a dependency on the `league/oauth2-client` package. Alternatively, copy the contents of the PHPMailer folder into somewhere that's in your PHP `include_path` setting. If you don't speak git or just want a tarball, click the 'zip' button at the top of the page in GitHub. diff --git a/VERSION b/VERSION index 7ef7e8d8..1567ea7d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -5.2.11 \ No newline at end of file +5.2.12 \ No newline at end of file diff --git a/changelog.md b/changelog.md index 90c3a96b..63801ede 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,9 @@ # ChangeLog +## Version 5.2.12 (Sep 1st 2015) +* Fix incorrect composer package dependencies +* Skip existing embedded image `cid`s in `msgHTML` + ## Version 5.2.11 (Aug 31st 2015) * Don't switch to quoted-printable for long lines if already using base64 * Fixed Travis-CI config when run on PHP 7 diff --git a/class.phpmailer.php b/class.phpmailer.php index a209e2f7..9b11eca3 100644 --- a/class.phpmailer.php +++ b/class.phpmailer.php @@ -31,7 +31,7 @@ class PHPMailer * The PHPMailer Version number. * @type string */ - public $Version = '5.2.11'; + public $Version = '5.2.12'; /** * Email priority. diff --git a/class.pop3.php b/class.pop3.php index d6d9b374..572ef2c0 100644 --- a/class.pop3.php +++ b/class.pop3.php @@ -34,7 +34,7 @@ class POP3 * @type string * @access public */ - public $Version = '5.2.11'; + public $Version = '5.2.12'; /** * Default POP3 port number. diff --git a/class.smtp.php b/class.smtp.php index 055dc1ff..b5876d08 100644 --- a/class.smtp.php +++ b/class.smtp.php @@ -30,7 +30,7 @@ class SMTP * The PHPMailer SMTP version number. * @type string */ - const VERSION = '5.2.11'; + const VERSION = '5.2.12'; /** * SMTP line break constant. @@ -81,7 +81,7 @@ class SMTP * @deprecated Use the `VERSION` constant instead * @see SMTP::VERSION */ - public $Version = '5.2.11'; + public $Version = '5.2.12'; /** * SMTP server port number.