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] 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';