From 749e9a3a9df3044e0f9767e5684db24aa2d8f897 Mon Sep 17 00:00:00 2001
From: decomplexity <65123375+decomplexity@users.noreply.github.com>
Date: Sat, 23 Mar 2024 20:29:21 +0000
Subject: [PATCH 1/2] OAuth2 for MSFT and Google API with authorization_code or
client_credentials
Client secrets and X.509 certificates, $_SESSION 'state' and PKCE code exchanges, and creation on the fly of GoogleAPI's .json credentials files are supported.
---
examples/sendoauth2.phps | 100 ++++++++++++++++++++++-----------------
1 file changed, 56 insertions(+), 44 deletions(-)
diff --git a/examples/sendoauth2.phps b/examples/sendoauth2.phps
index 84d93a17..c7c1c4ee 100644
--- a/examples/sendoauth2.phps
+++ b/examples/sendoauth2.phps
@@ -1,77 +1,89 @@
=6.6.0 that added support for oauthTokenProvider
- *
- * (The next release [V4] of the wrapper will replace TheLeague's Google provider by Google's own GoogleOauthClient;
- * this will provide support for Google's version of client credentials (Service Accounts) and client certificates)
+ * The wrapper can also be invoked using less (or even no) arguments; this is for those websites
+ * that use PHPMailer in several places. See the repo for details.
*/
-//Import SendOauth2B class into the global namespace
+// Uncomment the next two lines to display PHP errors
+// error_reporting(E_ALL);
+// ini_set("display_errors", 1);
+
+
+// Load Composer's autoloader
+require 'vendor/autoload.php';
+
+// Import SendOauth2B class into the global namespace
use decomplexity\SendOauth2\SendOauth2B;
-//Import PHPMailer classes into the global namespace
-//These must be at the top of your script, not inside a function
+
+// Import PHPMailer classes into the global namespace
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
-//Load Composer's autoloader
-require 'vendor/autoload.php';
+// Set timezone for SMTP
+date_default_timezone_set('Etc/UTC');
-//Create an instance; passing `true` enables exceptions
+// Create an instance; passing `true` enables exceptions
$mail = new PHPMailer(true);
try {
- //Server settings
- $mail->SMTPDebug = SMTP::DEBUG_SERVER; //Enable verbose debug output
- $mail->isSMTP(); //Send using SMTP
- $mail->Host = 'smtp.office365.com'; //Set the SMTP server (smtp.gmail.com for Gmail)
- $mail->SMTPAuth = true; //Enable SMTP authentication
- $mail->Username = 'user@example.com'; //SMTP username
- $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; //Enable implicit TLS encryption
- $mail->Port = 465; //TCP port to connect to
- $mail->AuthType = 'XOAUTH2'; // Set AuthType to use XOAUTH2
+ // Server settings
+ $mail->SMTPDebug = SMTP::DEBUG_OFF; // Set DEBUG_LOWLEVEL for SMTP diagnostics
+ $mail->isSMTP(); // Use SMTP
+ $mail->SMTPAuth = true; // Enable SMTP authentication
+ $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // Enable implicit TLS encryption
+ $mail->Port = 587; // TCP port; MSFT doesn't like 465
+ $mail->AuthType = 'XOAUTH2'; // Set AuthType to use XOAUTH2 ('LOGIN' for Basic auth)
- //Sender and recipients
+ // Sender and recipients
$mail->setFrom('from@example.com', 'Mailer'); // 'Header' From address with optional sender name
- $mail->addAddress('joe@example.net', 'Joe User'); //Add a recipient
+ $mail->addAddress('joe@example.net', 'Joe User'); // Add a To: recipient
- //Authentication
+ /**
+ * Authenticate
+ * Note that any ClientCertificatePrivateKey should include the -----BEGIN PRIVATE KEY----- and
+ * -----END PRIVATE KEY-----
+ */
+
$oauthTokenProvider = new SendOauth2B(
['mail' => $mail, // PHPMailer instance
- 'tenant' => 'long string', // tenant GUID or domain name. Null for Gmail
- 'clientId' => 'long string',
+ 'clientId' => 'long string', // for Google service account, Unique ID
'clientSecret' => 'long string', // or null if using a certificate
- 'clientCertificatePrivateKey' => 'extremely long string', // or null if using a clientSecret
+ 'clientCertificatePrivateKey' => 'ultra long string', // or null if using a clientSecret
'clientCertificateThumbprint' => 'long string', // or null if using a clientSecret
- 'serviceProvider' => 'Microsoft', // or Google
+ 'serviceProvider' => 'Microsoft', // literal: also 'Google' or 'GoogleAPI'
'authTypeSetting' => $mail->AuthType, // is set above - or insert here as 'XOAUTH2'
'mailSMTPAddress' => 'me@mydomain.com', // Envelope/mailFrom/reverse-path From address
- 'hostedDomain' => 'mydomain.com', // Google only (and optional)
- 'refreshToken' => 'very long string',
- 'grantTypeValue' => 'authorization_code', // or 'client_credentials' (Microsoft only)
+ 'refreshToken' => 'very long string', // null if grantType is 'client_credentials'
+ 'grantType' => 'authorization_code', // or 'client_credentials'
+
+ 'tenant' => 'long string', // MSFT tenant GUID. Null for Gmail
+
+ 'hostedDomain' => 'mydomain.com', // Any Google (and optional). Null for MSFT
+ 'projectID' => 'string', // GoogleAPI only. Else null
+ 'serviceAccountName' => 'string', // GoogleAPI service account only. Else null
+ 'impersonate' => 'you@mydomain.com', // Google API service account only. Else null
+ // (Google Wspace email adddress, not @gmail)
]
);
- /**
- * If an argument (above) has a null value, the argument can be omitted altogether.
- * ClientCertificatePrivateKey should include the -----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY-----
- */
+
- $mail->setOAuth($oauthTokenProvider); //Pass OAuthTokenProvider to PHPMailer
+ $mail->setOAuth($oauthTokenProvider); // Pass OAuthTokenProvider to PHPMailer
+ $mail->Host = 'smtp.office365.com'; // Set SMTP server (smtp.gmail.com for Gmail)
- //Content
- $mail->isHTML(true); //Set email format to HTML
+ // Content
+ $mail->isHTML(true); // Set email format to HTML
$mail->Subject = 'Here is the subject';
$mail->Body = 'This is the HTML message body in bold!';
$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
From 5d698fc44dc48b373124106f8e420c5ce5450b3f Mon Sep 17 00:00:00 2001
From: Marcus Bointon
Date: Tue, 26 Mar 2024 18:26:42 +0100
Subject: [PATCH 2/2] Cleanup
---
examples/sendoauth2.phps | 67 ++++++++++++++++++++--------------------
1 file changed, 33 insertions(+), 34 deletions(-)
diff --git a/examples/sendoauth2.phps b/examples/sendoauth2.phps
index c7c1c4ee..97ed0cdf 100644
--- a/examples/sendoauth2.phps
+++ b/examples/sendoauth2.phps
@@ -11,26 +11,24 @@
*
* The wrapper is installed with Composer from the decomplexity/SendOauth2 repo; see its README.
*
- * The wrapper can also be invoked using less (or even no) arguments; this is for those websites
+ * The wrapper can also be invoked using fewer (or even no) arguments; this is for those websites
* that use PHPMailer in several places. See the repo for details.
*/
+// Import PHPMailer classes
+use PHPMailer\PHPMailer\PHPMailer;
+use PHPMailer\PHPMailer\SMTP;
+use PHPMailer\PHPMailer\Exception;
+// Import SendOauth2B class
+use decomplexity\SendOauth2\SendOauth2B;
+
// Uncomment the next two lines to display PHP errors
// error_reporting(E_ALL);
// ini_set("display_errors", 1);
-
// Load Composer's autoloader
require 'vendor/autoload.php';
-// Import SendOauth2B class into the global namespace
-use decomplexity\SendOauth2\SendOauth2B;
-
-// Import PHPMailer classes into the global namespace
-use PHPMailer\PHPMailer\PHPMailer;
-use PHPMailer\PHPMailer\SMTP;
-use PHPMailer\PHPMailer\Exception;
-
// Set timezone for SMTP
date_default_timezone_set('Etc/UTC');
@@ -39,8 +37,8 @@ $mail = new PHPMailer(true);
try {
// Server settings
- $mail->SMTPDebug = SMTP::DEBUG_OFF; // Set DEBUG_LOWLEVEL for SMTP diagnostics
$mail->isSMTP(); // Use SMTP
+ $mail->SMTPDebug = SMTP::DEBUG_OFF; // Set DEBUG_LOWLEVEL for SMTP diagnostics
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // Enable implicit TLS encryption
$mail->Port = 587; // TCP port; MSFT doesn't like 465
@@ -50,34 +48,35 @@ try {
$mail->setFrom('from@example.com', 'Mailer'); // 'Header' From address with optional sender name
$mail->addAddress('joe@example.net', 'Joe User'); // Add a To: recipient
- /**
+ /**
* Authenticate
* Note that any ClientCertificatePrivateKey should include the -----BEGIN PRIVATE KEY----- and
* -----END PRIVATE KEY-----
*/
-
+
$oauthTokenProvider = new SendOauth2B(
- ['mail' => $mail, // PHPMailer instance
- 'clientId' => 'long string', // for Google service account, Unique ID
- 'clientSecret' => 'long string', // or null if using a certificate
- 'clientCertificatePrivateKey' => 'ultra long string', // or null if using a clientSecret
- 'clientCertificateThumbprint' => 'long string', // or null if using a clientSecret
- 'serviceProvider' => 'Microsoft', // literal: also 'Google' or 'GoogleAPI'
- 'authTypeSetting' => $mail->AuthType, // is set above - or insert here as 'XOAUTH2'
- 'mailSMTPAddress' => 'me@mydomain.com', // Envelope/mailFrom/reverse-path From address
- 'refreshToken' => 'very long string', // null if grantType is 'client_credentials'
- 'grantType' => 'authorization_code', // or 'client_credentials'
-
- 'tenant' => 'long string', // MSFT tenant GUID. Null for Gmail
-
- 'hostedDomain' => 'mydomain.com', // Any Google (and optional). Null for MSFT
- 'projectID' => 'string', // GoogleAPI only. Else null
- 'serviceAccountName' => 'string', // GoogleAPI service account only. Else null
- 'impersonate' => 'you@mydomain.com', // Google API service account only. Else null
- // (Google Wspace email adddress, not @gmail)
- ]
+ [
+ 'mail' => $mail, // PHPMailer instance
+ 'clientId' => 'long string', // for Google service account, Unique ID
+ 'clientSecret' => 'long string', // or null if using a certificate
+ 'clientCertificatePrivateKey' => 'ultra long string', // or null if using a clientSecret
+ 'clientCertificateThumbprint' => 'long string', // or null if using a clientSecret
+ 'serviceProvider' => 'Microsoft', // literal: also 'Google' or 'GoogleAPI'
+ 'authTypeSetting' => $mail->AuthType, // is set above - or insert here as 'XOAUTH2'
+ 'mailSMTPAddress' => 'me@mydomain.com', // Envelope/mailFrom/reverse-path From address
+ 'refreshToken' => 'very long string', // null if grantType is 'client_credentials'
+ 'grantType' => 'authorization_code', // or 'client_credentials'
+
+ 'tenant' => 'long string', // MSFT tenant GUID. Null for Gmail
+
+ 'hostedDomain' => 'mydomain.com', // Any Google (and optional). Null for MSFT
+ 'projectID' => 'string', // GoogleAPI only. Else null
+ 'serviceAccountName' => 'string', // GoogleAPI service account only. Else null
+ 'impersonate' => 'you@mydomain.com', // Google API service account only. Else null
+ // (Google Wspace email adddress, not @gmail)
+ ]
);
-
+
$mail->setOAuth($oauthTokenProvider); // Pass OAuthTokenProvider to PHPMailer
$mail->Host = 'smtp.office365.com'; // Set SMTP server (smtp.gmail.com for Gmail)
@@ -91,5 +90,5 @@ try {
$mail->send();
echo 'Message has been sent';
} catch (Exception $e) {
- echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
+ echo 'Message could not be sent. Mailer Error: ' . htmlspecialchars($mail->ErrorInfo, ENT_QUOTES);
}