PluginProbe ʕ •ᴥ•ʔ
Check & Log Email – Easy Email Testing & Mail logging / 2.0.5.1
Check & Log Email – Easy Email Testing & Mail logging v2.0.5.1
1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 2.0 2.0.1 2.0.10 2.0.11 2.0.12 2.0.13 2.0.13.1 2.0.13.2 2.0.14 2.0.2 2.0.3 2.0.4 2.0.5 2.0.5.1 2.0.6 2.0.7 2.0.8 2.0.9 trunk 0.5.7 0.6.0 0.6.1 0.6.2 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.12.1 1.0.13 1.0.13.1 1.0.2 1.0.3
check-email / include / Core / Auth.php
check-email / include / Core Last commit date
DB 1 year ago Request 1 year ago UI 1 year ago Auth.php 1 year ago Check_Email_Admin_Capability_Giver.php 1 year ago Check_Email_Export_Log.php 1 year ago Check_Email_From_Handler.php 1 year ago Check_Email_Log.php 1 year ago Check_Email_Logger.php 1 year ago Check_Email_Multisite.php 1 year ago Check_Email_Review.php 1 year ago Loadie.php 1 year ago
Auth.php
510 lines
1 <?php
2
3
4 namespace CheckEmail\Core;
5
6 $check_email = wpchill_check_email();
7 $plugin_path = plugin_dir_path($check_email->get_plugin_file());
8 require_once $plugin_path . '/vendor/autoload.php';
9
10 use Exception;
11 use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
12 use League\OAuth2\Client\Provider\GenericProvider;
13 use League\OAuth2\Client\Token\AccessToken;
14 use League\OAuth2\Client\Token\AccessTokenInterface;
15
16 class Auth
17 {
18
19 /**
20 * Scopes that we need to send emails.
21 *
22 * @since 1.5.0
23 */
24 const SCOPES = [
25 'https://graph.microsoft.com/mail.send',
26 'https://graph.microsoft.com/mail.send.shared',
27 'https://graph.microsoft.com/mail.readwrite',
28 'https://graph.microsoft.com/user.read',
29 'offline_access',
30 ];
31 public $mailer = null;
32 public $options = [];
33 public $client = null;
34
35
36 public function __construct($mailer_type = null)
37 {
38 $this->mailer = $mailer_type;
39 $this->options = $this->get_mailer_option();
40 $this->get_client();
41 }
42
43
44 public function get_mailer_option()
45 {
46 $smtp_options = get_site_option('check-email-log-global-smtp');
47 if (isset($smtp_options['enable_global']) && ! empty($smtp_options['enable_global']) && is_multisite()) {
48 return get_site_option('check-email-log-' . $this->mailer . '-options');
49 } else {
50 return get_option('check-email-log-' . $this->mailer . '-options');
51 }
52 }
53 public function update_mailer_option($options_to_update)
54 {
55
56 $smtp_options = get_site_option('check-email-log-global-smtp');
57 if (isset($smtp_options['enable_global']) && ! empty($smtp_options['enable_global']) && is_multisite()) {
58 $site_option = get_site_option('check-email-log-' . $this->mailer . '-options');
59 $mailer_options = array_merge((array)$site_option, (array)$options_to_update);
60 update_site_option('check-email-log-' . $this->mailer . '-options', $mailer_options);
61 } else {
62 $site_option = empty(get_option('check-email-log-' . $this->mailer . '-options')) ? [] : get_option('check-email-log-' . $this->mailer . '-options');
63 $mailer_options = array_merge((array)$site_option, (array)$options_to_update);
64 update_option('check-email-log-' . $this->mailer . '-options', $mailer_options);
65 }
66 $this->options = $this->get_mailer_option();
67 }
68 public function get_client() {
69
70 // Doesn't load client twice + gives ability to overwrite.
71 if (! empty($this->client)) {
72 return $this->client;
73 }
74
75 $authorize_url = 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize';
76
77
78 $access_token_url = 'https://login.microsoftonline.com/common/oauth2/v2.0/token';
79
80
81 $resource_owner_details_url = 'https://graph.microsoft.com/v1.0/me';
82 if (! isset($this->options['client_id']) && ! isset($this->options['client_secret'])) {
83 return null;
84 }
85
86 $this->client = new GenericProvider(
87 // $provider = new GenericProvider(
88 [
89 'clientId' => base64_decode($this->options['client_id']),
90 'clientSecret' => base64_decode($this->options['client_secret']),
91 'redirectUri' => self::get_plugin_auth_url(),
92 'urlAuthorize' => $authorize_url,
93 'urlAccessToken' => $access_token_url,
94 'urlResourceOwnerDetails' => $resource_owner_details_url,
95 'scopes' => 'openid profile User.Read Mail.Read Mail.Send',
96 ]
97 );
98
99
100 // Do not process if we don't have both App ID & Password.
101 if (! $this->is_clients_saved()) {
102 return $this->client;
103 }
104
105 if (! empty($this->options['access_token'])) {
106 $access_token = new AccessToken((array) $this->options['access_token']);
107 }
108
109 // We don't have tokens but have auth code.
110 if (
111 $this->is_auth_required() &&
112 ! empty($this->options['auth_code'])
113 ) {
114
115 // Try to get an access token using the authorization code grant.
116 $this->obtain_access_token();
117 } else { // We have tokens.
118
119 // Update the old token if needed.
120 if (! empty($access_token) && $access_token->hasExpired()) {
121 $this->refresh_access_token($access_token);
122 }
123 }
124
125 return $this->client;
126 }
127
128 /**
129 * Try to get an access token using the authorization code grant.
130 *
131 * @since 3.4.0
132 */
133 public function obtain_access_token() {
134
135 if (empty($this->options['auth_code'])) {
136 return;
137 }
138
139 try {
140 $access_token = $this->client->getAccessToken(
141 'authorization_code',
142 ['code' => $this->options['auth_code']]
143 );
144
145 $this->update_access_token($access_token->jsonSerialize());
146 // $this->update_refresh_token( $access_token->getRefreshToken() );
147 $this->update_user_details($access_token);
148 // $this->update_scopes( $this->get_scopes() );
149
150 // Reset Auth code. It's valid for 5 minutes anyway.
151 $this->update_auth_code('');
152
153 // Debug::clear();
154 } catch (IdentityProviderException $e) {
155 $response = $e->getResponseBody();
156
157 // error_log(print_r($response, true));
158
159
160 $this->update_auth_code('');
161 } catch (Exception $e) { // Catch any other general exceptions just in case.
162 // error_log(print_r($e->getMessage(), true));
163 $this->update_auth_code('');
164 }
165 }
166
167 private function refresh_access_token($access_token)
168 {
169 try {
170 $new_access_token = $this->client->getAccessToken(
171 'refresh_token',
172 ['refresh_token' => $access_token->getRefreshToken()]
173 );
174
175 $this->update_access_token($new_access_token->jsonSerialize());
176 $this->update_refresh_token($new_access_token->getRefreshToken());
177 $this->update_user_details($new_access_token);
178 } catch (IdentityProviderException $e) {
179 $response = $e->getResponseBody();
180
181
182 } catch (Exception $e) { // Catch any other general exception just in case.
183
184 // $e->getMessage()
185 }
186 }
187
188
189 public static function get_plugin_auth_url()
190 {
191 $smtp_options = get_site_option('check-email-log-global-smtp');
192 if (isset($smtp_options['enable_global']) && ! empty($smtp_options['enable_global']) && is_multisite()) {
193 return network_admin_url();
194 } else {
195 return admin_url();
196 }
197 }
198
199
200 public function process_auth($code)
201 {
202
203 $this->update_auth_code($code);
204
205 // Remove old errors.
206 Debug::clear();
207
208 // Retrieve the token and user details, save errors if any.
209 $this->get_client();
210 }
211
212
213 public function get_auth_url() {
214 $client = $this->get_client();
215 if (
216 ! empty($client) &&
217 class_exists('\League\OAuth2\Client\Provider\GenericProvider', false) &&
218 $client instanceof GenericProvider
219 ) {
220 $url_options = [
221 'state' => $this->get_state(),
222 'scope' => $this->get_scopes(),
223 ];
224
225 $auth_url = $client->getAuthorizationUrl($url_options);
226
227 return $auth_url;
228 }
229
230 return '#';
231 }
232
233 /**
234 * Get auth scopes.
235 *
236 * @since 2.8.0
237 *
238 * @return array
239 */
240 protected function get_scopes()
241 {
242
243 return self::SCOPES;
244 }
245
246
247 public function update_user_details($access_token)
248 {
249 $user = [
250 'display_name' => '',
251 'email' => '',
252 ];
253
254 try {
255 $resource_owner = $this->get_client()->getResourceOwner($access_token);
256 $resource_data = $resource_owner->toArray();
257
258 $user = [
259 'display_name' => $resource_data['displayName'],
260 'email' => $resource_data['userPrincipalName'],
261 ];
262 } catch (IdentityProviderException $e) {
263 $response = $e->getResponseBody();
264
265
266 // Reset Auth code. It's valid for 5 minutes anyway.
267 $this->update_auth_code( '' );
268 } catch (Exception $e) {
269 return $e->getMessage();
270 // Catch general any other exception just in case.
271 // Debug::set(
272 // 'Mailer: Outlook (requesting user details)' . WP::EOL .
273 // $e->getMessage()
274 // );
275 }
276
277
278 $site_option['user_details'] = $user;
279
280 $this->update_mailer_option($site_option);
281 }
282
283
284 protected function get_state()
285 {
286 return 'check-email-nonce_'.wp_create_nonce('ck_mail_outlook_check_nonce');
287 }
288
289 public function is_clients_saved()
290 {
291 return ! empty($this->options['client_id']) && ! empty($this->options['client_secret']);
292 }
293
294 public function is_auth_required()
295 {
296 return empty($this->options['access_token']);
297 }
298 public function update_access_token($access_token)
299 {
300 $smtp_options = get_site_option('check-email-log-global-smtp');
301 if (isset($smtp_options['enable_global']) && ! empty($smtp_options['enable_global']) && is_multisite()) {
302 $site_option = get_site_option('check-email-log-' . $this->mailer . '-options');
303 $site_option['access_token'] = $access_token;
304 update_site_option('check-email-log-' . $this->mailer . '-options', $site_option);
305 } else {
306 $site_option = get_option('check-email-log-' . $this->mailer . '-options');
307 $site_option['access_token'] = $access_token;
308 update_option('check-email-log-' . $this->mailer . '-options', $site_option);
309 }
310 $this->options = $this->get_mailer_option();
311 }
312
313 public function update_refresh_token($access_token)
314 {
315 $smtp_options = get_site_option('check-email-log-global-smtp');
316 if (isset($smtp_options['enable_global']) && ! empty($smtp_options['enable_global']) && is_multisite()) {
317 $site_option = get_site_option('check-email-log-' . $this->mailer . '-options');
318 $site_option['refresh_token'] = $access_token;
319 update_site_option('check-email-log-' . $this->mailer . '-options', $site_option);
320 } else {
321 $site_option = get_option('check-email-log-' . $this->mailer . '-options');
322 $site_option['refresh_token'] = $access_token;
323 update_option('check-email-log-' . $this->mailer . '-options', $site_option);
324 }
325 $this->options = $this->get_mailer_option();
326 }
327
328 public function update_auth_code($code) {
329 $smtp_options = get_site_option('check-email-log-global-smtp');
330 if (isset($smtp_options['enable_global']) && ! empty($smtp_options['enable_global']) && is_multisite()) {
331 $site_option = get_site_option('check-email-log-' . $this->mailer . '-options');
332 $site_option['auth_code'] = $code;
333 update_site_option('check-email-log-' . $this->mailer . '-options', $site_option);
334 } else {
335 $site_option = get_option('check-email-log-' . $this->mailer . '-options');
336 $site_option['auth_code'] = $code;
337 update_option('check-email-log-' . $this->mailer . '-options', $site_option);
338 }
339 $this->options = $this->get_mailer_option();
340
341 // We don't have tokens but have auth code.
342 if ($this->is_auth_required() && ! empty($this->options['auth_code'])) {
343 // Try to get an access token using the authorization code grant.
344 $this->obtain_access_token();
345 }
346 }
347
348 function sendEmailByMailer($from_email, $to_email, $subject, $body) {
349
350 // Get the access token from options
351 $access_token_array = $this->options['access_token'];
352 $access_token = $access_token_array['access_token'];
353
354 // Graph API URL for sending mail
355 $url = "https://graph.microsoft.com/v1.0/me/sendMail";
356
357 // Email message structure
358 $message = [
359 "message" => [
360 "subject" => $subject,
361 "body" => [
362 "contentType" => "HTML",
363 "content" => $body,
364 ],
365 "toRecipients" => [
366 [
367 "emailAddress" => [
368 "address" => $to_email,
369 ],
370 ],
371 ],
372 ],
373 "saveToSentItems" => "true", // Save a copy to Sent Items folder
374 ];
375
376 // Request arguments
377 $args = [
378 'headers' => [
379 "Authorization" => "Bearer $access_token", // Authorization header
380 'Content-Type' => 'application/json', // JSON content type
381 ],
382 'body' => wp_json_encode($message), // JSON encode the message
383 'timeout' => 45, // Optional timeout, increase if necessary
384 'sslverify' => true, // Verify SSL (set to false only if you're sure)
385 ];
386
387 // Make the API request using wp_remote_post
388 $response = wp_remote_post($url, $args);
389
390 // Check for errors in the response
391 if (is_wp_error($response)) {
392 return [
393 'error' => 1,
394 'message' => $response->get_error_message(), // Return the error message
395 ];
396 }
397
398 // Optional: Check the email log and forward if necessary
399 $setting_options = get_option('check-email-log-core');
400 if (isset($setting_options['forward_email']) && !empty($setting_options['forward_email'])) {
401 $this->forward_email_by_mailer($to_email, $subject, $body);
402 }
403
404 // If everything is fine, return success
405 return [
406 'error' => 0,
407 'message' => "", // Empty message means no errors
408 ];
409 }
410
411
412 function forward_email_by_mailer($to_email, $subject, $body) {
413 // Get the access token
414 $access_token_array = $this->options['access_token'];
415 $access_token = $access_token_array['access_token'];
416
417
418 // Graph API URL
419 $url = "https://graph.microsoft.com/v1.0/me/sendMail";
420 $toRecipients = [];
421 $ccRecipients = [];
422 $bccRecipients = [];
423 if (isset($setting_options['forward_email']) && !empty($setting_options['forward_email'])) {
424 if (isset($setting_options['forward_to']) && !empty($setting_options['forward_to'])) {
425 $to_email = explode(',', $setting_options['forward_to']);
426
427
428 foreach ((array) $to_email as $email) {
429 $toRecipients[] = [
430 "emailAddress" => [
431 "address" => $email,
432 ],
433 ];
434 }
435 }
436
437
438 if (isset($setting_options['forward_cc']) && !empty($setting_options['forward_cc'])) {
439 $copy_to = explode(',', $setting_options['forward_cc']);
440 foreach ((array) $copy_to as $email) {
441 $ccRecipients[] = [
442 "emailAddress" => [
443 "address" => $email,
444 ],
445 ];
446 }
447 }
448
449 if (isset($setting_options['forward_bcc']) && !empty($setting_options['forward_bcc'])) {
450 $bcc_to = explode(',', $setting_options['forward_bcc']);
451 foreach ((array) $bcc_to as $email) {
452 $bccRecipients[] = [
453 "emailAddress" => [
454 "address" => $email,
455 ],
456 ];
457 }
458 }
459 }
460
461 $message = [
462 "message" => [
463 "subject" => $subject,
464 "body" => [
465 "contentType" => "HTML",
466 "content" => $body,
467 ],
468 "toRecipients" => $toRecipients,
469 "ccRecipients" => $ccRecipients,
470 "bccRecipients" => $bccRecipients,
471 ],
472 "saveToSentItems" => "true",
473 ];
474
475 // Arguments for the request
476 $args = [
477 'headers' => [
478 "Authorization" => "Bearer $access_token",
479 'Content-Type' => 'application/json',
480 ],
481 'body' => wp_json_encode($message),
482 ];
483
484 $response = wp_remote_post($url, $args);
485
486 // Check for errors
487 if (is_wp_error($response)) {
488 return [
489 'error' => 1,
490 'message' => $response->get_error_message(),
491 ];
492 }
493
494 return [
495 'error' => 0,
496 'message' => "",
497 ];
498 }
499
500 public function delete_outlook_options() {
501 $smtp_options = get_site_option('check-email-log-global-smtp');
502 if (isset($smtp_options['enable_global']) && ! empty($smtp_options['enable_global']) && is_multisite()) {
503 delete_site_option('check-email-log-' . $this->mailer . '-options');
504 } else {
505 delete_option('check-email-log-' . $this->mailer . '-options');
506 }
507 $this->options = $this->get_mailer_option();
508 }
509 }
510