Post SMTP Mailer/Email Log - Version 2.0.4

Version Description

  • 2019-08-27
  • Updated: More security.
Download this release

Release Info

Developer yehudah
Plugin Icon 128x128 Post SMTP Mailer/Email Log
Version 2.0.4
Comparing to
See all releases

Code changes from version 2.0.3 to 2.0.4

Postman/Postman-Connectivity-Test/PostmanConnectivityTestController.php CHANGED
@@ -98,6 +98,14 @@ class PostmanConnectivityTestController {
98
  wp_enqueue_script( 'postman_port_test_script' );
99
  $warning = __( 'Warning', 'post-smtp' );
100
  wp_localize_script( PostmanViewController::POSTMAN_SCRIPT, 'postman_hostname_element_name', '#input_' . PostmanOptions::HOSTNAME );
 
 
 
 
 
 
 
 
101
  PostmanConnectivityTestController::addLocalizeScriptForPortTest();
102
  }
103
  static function addLocalizeScriptForPortTest() {
@@ -135,6 +143,8 @@ class PostmanConnectivityTestController {
135
  public function outputPortTestContent() {
136
  print '<div class="wrap">';
137
 
 
 
138
  PostmanViewController::outputChildPageHeader( __( 'Connectivity Test', 'post-smtp' ) );
139
 
140
  print '<p>';
98
  wp_enqueue_script( 'postman_port_test_script' );
99
  $warning = __( 'Warning', 'post-smtp' );
100
  wp_localize_script( PostmanViewController::POSTMAN_SCRIPT, 'postman_hostname_element_name', '#input_' . PostmanOptions::HOSTNAME );
101
+ wp_localize_script( PostmanViewController::POSTMAN_SCRIPT, 'postman_email_test', array(
102
+ 'recipient' => '#' . PostmanSendTestEmailController::RECIPIENT_EMAIL_FIELD_NAME,
103
+ 'not_started' => _x( 'In Outbox', 'Email Test Status', 'post-smtp' ),
104
+ 'sending' => _x( 'Sending...', 'Email Test Status', 'post-smtp' ),
105
+ 'success' => _x( 'Success', 'Email Test Status', 'post-smtp' ),
106
+ 'failed' => _x( 'Failed', 'Email Test Status', 'post-smtp' ),
107
+ 'ajax_error' => __( 'Ajax Error', 'post-smtp' ),
108
+ ) );
109
  PostmanConnectivityTestController::addLocalizeScriptForPortTest();
110
  }
111
  static function addLocalizeScriptForPortTest() {
143
  public function outputPortTestContent() {
144
  print '<div class="wrap">';
145
 
146
+ wp_nonce_field('post-smtp', 'security');
147
+
148
  PostmanViewController::outputChildPageHeader( __( 'Connectivity Test', 'post-smtp' ) );
149
 
150
  print '<p>';
Postman/Postman-Connectivity-Test/postman_port_test.js CHANGED
@@ -73,7 +73,7 @@ function portQuizTest(socket, hostname, port) {
73
  'action' : 'postman_port_quiz_test',
74
  'hostname' : hostname,
75
  'port' : port,
76
- '_wpnonce' : jQuery('#_wpnonce').val(),
77
  };
78
  jQuery.post(
79
  ajaxurl,
@@ -201,7 +201,7 @@ function portTest3(socket, hostname, port, open) {
201
  'action' : 'postman_test_smtps',
202
  'hostname' : hostname,
203
  'port' : port,
204
- '_wpnonce' : jQuery('#_wpnonce').val(),
205
  };
206
  jQuery
207
  .post(
73
  'action' : 'postman_port_quiz_test',
74
  'hostname' : hostname,
75
  'port' : port,
76
+ 'security' : jQuery('#security').val(),
77
  };
78
  jQuery.post(
79
  ajaxurl,
201
  'action' : 'postman_test_smtps',
202
  'hostname' : hostname,
203
  'port' : port,
204
+ 'security' : jQuery('#security').val(),
205
  };
206
  jQuery
207
  .post(
Postman/Postman-Email-Log/PostmanEmailLogController.php CHANGED
@@ -3,7 +3,7 @@ if ( ! defined( 'ABSPATH' ) ) {
3
  exit; // Exit if accessed directly
4
  }
5
 
6
- require_once dirname(__DIR__) . '/PostmanEmailLogs.php';
7
  require_once 'PostmanEmailLogService.php';
8
  require_once 'PostmanEmailLogView.php';
9
 
@@ -82,7 +82,7 @@ class PostmanEmailLogController {
82
  // get the email address of the recipient from the HTTP Request
83
  $postid = $this->getRequestParameter( 'email' );
84
  if ( ! empty( $postid ) ) {
85
- $meta_values = PostmanEmailLogs::get_data( $postid );
86
 
87
  if ( isset( $_POST['mail_to'] ) && ! empty( $_POST['mail_to'] ) ) {
88
  $emails = explode( ',', $_POST['mail_to'] );
@@ -211,7 +211,7 @@ class PostmanEmailLogController {
211
  return;
212
  }
213
 
214
- $meta_values = PostmanEmailLogs::get_data( $postid );
215
  // https://css-tricks.com/examples/hrs/
216
  print '<html><head><style>body {font-family: monospace;} hr {
217
  border: 0;
@@ -269,7 +269,7 @@ class PostmanEmailLogController {
269
  $this->logger->trace( 'handling view transcript item' );
270
  $postid = $_REQUEST ['email'];
271
  $post = get_post( $postid );
272
- $meta_values = PostmanEmailLogs::get_data( $postid );
273
  // https://css-tricks.com/examples/hrs/
274
  print '<html><head><style>body {font-family: monospace;} hr {
275
  border: 0;
3
  exit; // Exit if accessed directly
4
  }
5
 
6
+ require_once dirname(__DIR__) . '/PostmanLogFields.php';
7
  require_once 'PostmanEmailLogService.php';
8
  require_once 'PostmanEmailLogView.php';
9
 
82
  // get the email address of the recipient from the HTTP Request
83
  $postid = $this->getRequestParameter( 'email' );
84
  if ( ! empty( $postid ) ) {
85
+ $meta_values = PostmanLogFields::get_instance()->get( $postid );
86
 
87
  if ( isset( $_POST['mail_to'] ) && ! empty( $_POST['mail_to'] ) ) {
88
  $emails = explode( ',', $_POST['mail_to'] );
211
  return;
212
  }
213
 
214
+ $meta_values = PostmanLogFields::get_instance()->get( $postid );
215
  // https://css-tricks.com/examples/hrs/
216
  print '<html><head><style>body {font-family: monospace;} hr {
217
  border: 0;
269
  $this->logger->trace( 'handling view transcript item' );
270
  $postid = $_REQUEST ['email'];
271
  $post = get_post( $postid );
272
+ $meta_values = PostmanLogFields::get_instance()->get( $postid );
273
  // https://css-tricks.com/examples/hrs/
274
  print '<html><head><style>body {font-family: monospace;} hr {
275
  border: 0;
Postman/Postman-Email-Log/PostmanEmailLogService.php CHANGED
@@ -3,6 +3,8 @@ if ( ! defined( 'ABSPATH' ) ) {
3
  exit; // Exit if accessed directly
4
  }
5
 
 
 
6
  if ( ! class_exists( 'PostmanEmailLog' ) ) {
7
  class PostmanEmailLog {
8
  public $sender;
@@ -153,32 +155,32 @@ if ( ! class_exists( 'PostmanEmailLogService' ) ) {
153
  $this->logger->trace( $log );
154
 
155
  // Write the meta data related to the email
156
- update_post_meta( $post_id, 'success', $log->success );
157
- update_post_meta( $post_id, 'from_header', $log->sender );
158
  if ( ! empty( $log->toRecipients ) ) {
159
- update_post_meta( $post_id, 'to_header', $log->toRecipients );
160
  }
161
  if ( ! empty( $log->ccRecipients ) ) {
162
- update_post_meta( $post_id, 'cc_header', $log->ccRecipients );
163
  }
164
  if ( ! empty( $log->bccRecipients ) ) {
165
- update_post_meta( $post_id, 'bcc_header', $log->bccRecipients );
166
  }
167
  if ( ! empty( $log->replyTo ) ) {
168
- update_post_meta( $post_id, 'reply_to_header', $log->replyTo );
169
  }
170
- update_post_meta( $post_id, 'transport_uri', $log->transportUri );
171
 
172
  if ( ! $log->success || true ) {
173
  // alwas add the meta data so we can re-send it
174
- update_post_meta( $post_id, 'original_to', $log->originalTo );
175
- update_post_meta( $post_id, 'original_subject', $log->originalSubject );
176
- update_post_meta( $post_id, 'original_message', $log->originalMessage );
177
- update_post_meta( $post_id, 'original_headers', $log->originalHeaders );
178
  }
179
 
180
  // we do not sanitize the session transcript - let the reader decide how to handle the data
181
- update_post_meta( $post_id, 'session_transcript', $log->sessionTranscript );
182
 
183
  // truncate the log (remove older entries)
184
  $purger = new PostmanEmailLogPurger();
3
  exit; // Exit if accessed directly
4
  }
5
 
6
+ require_once dirname(__DIR__ ) . '/PostmanLogFields.php';
7
+
8
  if ( ! class_exists( 'PostmanEmailLog' ) ) {
9
  class PostmanEmailLog {
10
  public $sender;
155
  $this->logger->trace( $log );
156
 
157
  // Write the meta data related to the email
158
+ PostmanLogFields::get_instance()->update( $post_id, 'success', $log->success );
159
+ PostmanLogFields::get_instance()->update( $post_id, 'from_header', $log->sender );
160
  if ( ! empty( $log->toRecipients ) ) {
161
+ PostmanLogFields::get_instance()->update( $post_id, 'to_header', $log->toRecipients );
162
  }
163
  if ( ! empty( $log->ccRecipients ) ) {
164
+ PostmanLogFields::get_instance()->update( $post_id, 'cc_header', $log->ccRecipients );
165
  }
166
  if ( ! empty( $log->bccRecipients ) ) {
167
+ PostmanLogFields::get_instance()->update( $post_id, 'bcc_header', $log->bccRecipients );
168
  }
169
  if ( ! empty( $log->replyTo ) ) {
170
+ PostmanLogFields::get_instance()->update( $post_id, 'reply_to_header', $log->replyTo );
171
  }
172
+ PostmanLogFields::get_instance()->update( $post_id, 'transport_uri', $log->transportUri );
173
 
174
  if ( ! $log->success || true ) {
175
  // alwas add the meta data so we can re-send it
176
+ PostmanLogFields::get_instance()->update( $post_id, 'original_to', $log->originalTo );
177
+ PostmanLogFields::get_instance()->update( $post_id, 'original_subject', $log->originalSubject );
178
+ PostmanLogFields::get_instance()->update( $post_id, 'original_message', $log->originalMessage );
179
+ PostmanLogFields::get_instance()->update( $post_id, 'original_headers', $log->originalHeaders );
180
  }
181
 
182
  // we do not sanitize the session transcript - let the reader decide how to handle the data
183
+ PostmanLogFields::get_instance()->update( $post_id, 'session_transcript', $log->sessionTranscript );
184
 
185
  // truncate the log (remove older entries)
186
  $purger = new PostmanEmailLogPurger();
Postman/Postman-Email-Log/PostmanEmailLogView.php CHANGED
@@ -2,7 +2,7 @@
2
  if ( ! defined( 'ABSPATH' ) ) {
3
  exit; // Exit if accessed directly
4
  }
5
- require_once dirname(__DIR__) . '/PostmanEmailLogs.php';
6
 
7
  /**
8
  * See http://wpengineer.com/2426/wp_list_table-a-step-by-step-guide/
@@ -96,7 +96,7 @@ class PostmanEmailLogView extends WP_List_Table {
96
  $transcriptUrl = admin_url( sprintf( $iframeUri, 'transcript', $item ['ID'] ) );
97
  $resendUrl = admin_url( sprintf( $iframeUri, 'resend', $item ['ID'] ) );
98
 
99
- $meta_values = PostmanEmailLogs::get_data( $item ['ID'] );
100
 
101
  $actions = array(
102
  'delete' => sprintf( '<a href="%s">%s</a>', $deleteUrl, _x( 'Delete', 'Delete an item from the email log', 'post-smtp' ) ),
@@ -373,7 +373,7 @@ class PostmanEmailLogView extends WP_List_Table {
373
  /* Translators: where %s indicates the relative time from now */
374
  $date = sprintf( _x( '%s ago', 'A relative time as in "five days ago"', 'post-smtp' ), $humanTime );
375
  }
376
- $meta_values = PostmanEmailLogs::get_data( $post->ID );
377
  $sent_to = array_map( 'sanitize_email', explode( ',' , $meta_values ['to_header'] [0] ) );
378
  $flattenedPost = array(
379
  // the post title must be escaped as they are displayed in the HTML output
2
  if ( ! defined( 'ABSPATH' ) ) {
3
  exit; // Exit if accessed directly
4
  }
5
+ require_once dirname(__DIR__) . '/PostmanLogFields.php';
6
 
7
  /**
8
  * See http://wpengineer.com/2426/wp_list_table-a-step-by-step-guide/
96
  $transcriptUrl = admin_url( sprintf( $iframeUri, 'transcript', $item ['ID'] ) );
97
  $resendUrl = admin_url( sprintf( $iframeUri, 'resend', $item ['ID'] ) );
98
 
99
+ $meta_values = PostmanLogFields::get_instance()->get( $item ['ID'] );
100
 
101
  $actions = array(
102
  'delete' => sprintf( '<a href="%s">%s</a>', $deleteUrl, _x( 'Delete', 'Delete an item from the email log', 'post-smtp' ) ),
373
  /* Translators: where %s indicates the relative time from now */
374
  $date = sprintf( _x( '%s ago', 'A relative time as in "five days ago"', 'post-smtp' ), $humanTime );
375
  }
376
+ $meta_values = PostmanLogFields::get_instance()->get( $post->ID );
377
  $sent_to = array_map( 'sanitize_email', explode( ',' , $meta_values ['to_header'] [0] ) );
378
  $flattenedPost = array(
379
  // the post title must be escaped as they are displayed in the HTML output
Postman/Postman-Mail/PostmanSmtpModuleTransport.php CHANGED
@@ -542,6 +542,8 @@ class PostmanSmtpModuleTransport extends PostmanAbstractZendModuleTransport impl
542
  printf( '<legend>%s</legend>', _x( 'Which host will relay the mail?', 'Wizard Step Title', 'post-smtp' ) );
543
  printf( '<p>%s</p>', __( 'This is the Outgoing (SMTP) Mail Server, or Mail Submission Agent (MSA), which Postman delegates mail delivery to. This server is specific to your email account, and if you don\'t know what to use, ask your email service provider.', 'post-smtp' ) );
544
  printf( '<p>%s</p>', __( 'Note that many WordPress hosts, such as GoDaddy, Bluehost and Dreamhost, require that you use their mail accounts with their mail servers, and prevent you from using others.', 'post-smtp' ) );
 
 
545
  printf( '<label for="hostname">%s</label>', __( 'Outgoing Mail Server Hostname', 'post-smtp' ) );
546
  print $this->hostname_callback();
547
  printf( '<p class="ajax-loader" style="display:none"><img src="%s"/></p>', plugins_url( 'post-smtp/style/ajax-loader.gif' ) );
542
  printf( '<legend>%s</legend>', _x( 'Which host will relay the mail?', 'Wizard Step Title', 'post-smtp' ) );
543
  printf( '<p>%s</p>', __( 'This is the Outgoing (SMTP) Mail Server, or Mail Submission Agent (MSA), which Postman delegates mail delivery to. This server is specific to your email account, and if you don\'t know what to use, ask your email service provider.', 'post-smtp' ) );
544
  printf( '<p>%s</p>', __( 'Note that many WordPress hosts, such as GoDaddy, Bluehost and Dreamhost, require that you use their mail accounts with their mail servers, and prevent you from using others.', 'post-smtp' ) );
545
+
546
+ printf( '<div><strong><u>%s</u></strong></div><br>', __( 'If you plan to use An API and not SMTP just type any value.', 'post-smtp' ) );
547
  printf( '<label for="hostname">%s</label>', __( 'Outgoing Mail Server Hostname', 'post-smtp' ) );
548
  print $this->hostname_callback();
549
  printf( '<p class="ajax-loader" style="display:none"><img src="%s"/></p>', plugins_url( 'post-smtp/style/ajax-loader.gif' ) );
Postman/Postman-Mail/Zend-1.12.10/Mail.php CHANGED
@@ -706,10 +706,21 @@ class Postman_Zend_Mail extends Postman_Zend_Mime_Message
706
  throw new Postman_Zend_Mail_Exception('Reply-To Header set twice');
707
  }
708
 
709
- $email = $this->_filterEmail($email);
710
  $name = $this->_filterName($name);
711
  $this->_replyTo = $email;
712
- $this->_storeHeader('Reply-To', $this->_formatAddress($email, $name), true);
 
 
 
 
 
 
 
 
 
 
 
 
713
 
714
  return $this;
715
  }
706
  throw new Postman_Zend_Mail_Exception('Reply-To Header set twice');
707
  }
708
 
 
709
  $name = $this->_filterName($name);
710
  $this->_replyTo = $email;
711
+
712
+ if ( strpos( $email, ',' ) !== false ) {
713
+ $emails = explode(',', $email );
714
+ foreach ( $emails as $email ) {
715
+ $email = $this->_filterEmail($email);
716
+ $replyToList[] = $this->_formatAddress($email, $name);
717
+ }
718
+ } else {
719
+ $email = $this->_filterEmail($email);
720
+ $replyToList[] = $this->_formatAddress($email, $name);
721
+ }
722
+
723
+ $this->_storeHeader('Reply-To', implode(',', $replyToList ), true);
724
 
725
  return $this;
726
  }
Postman/PostmanInputSanitizer.php CHANGED
@@ -93,6 +93,8 @@ if ( ! class_exists( 'PostmanInputSanitizer' ) ) {
93
  $this->sanitizeString( 'Fallback username', PostmanOptions::FALLBACK_SMTP_USERNAME, $input, $new_input );
94
  $this->sanitizePassword( 'Fallback password', PostmanOptions::FALLBACK_SMTP_PASSWORD, $input, $new_input, $this->options->getFallbackPassword() );
95
 
 
 
96
  if ( $new_input [ PostmanOptions::CLIENT_ID ] != $this->options->getClientId() || $new_input [ PostmanOptions::CLIENT_SECRET ] != $this->options->getClientSecret() || $new_input [ PostmanOptions::HOSTNAME ] != $this->options->getHostname() ) {
97
  $this->logger->debug( 'Recognized new Client ID' );
98
  // the user entered a new client id and we should destroy the stored auth token
@@ -115,7 +117,8 @@ if ( ! class_exists( 'PostmanInputSanitizer' ) ) {
115
 
116
  return $new_input;
117
  }
118
- private function sanitizeString( $desc, $key, $input, &$new_input ) {
 
119
  if ( isset( $input [ $key ] ) ) {
120
  $this->logSanitize( $desc, $input [ $key ] );
121
  $new_input [ $key ] = trim( $input [ $key ] );
@@ -130,7 +133,7 @@ if ( ! class_exists( 'PostmanInputSanitizer' ) ) {
130
  * @param mixed $input
131
  * @param mixed $new_input
132
  */
133
- private function sanitizePassword( $desc, $key, $input, &$new_input, $existingPassword ) {
134
  // WordPress calling Sanitize twice is a known issue
135
  // https://core.trac.wordpress.org/ticket/21989
136
  $action = PostmanSession::getInstance()->getAction();
93
  $this->sanitizeString( 'Fallback username', PostmanOptions::FALLBACK_SMTP_USERNAME, $input, $new_input );
94
  $this->sanitizePassword( 'Fallback password', PostmanOptions::FALLBACK_SMTP_PASSWORD, $input, $new_input, $this->options->getFallbackPassword() );
95
 
96
+ $new_input = apply_filters( 'post_smtp_sanitize', $new_input, $input, $this );
97
+
98
  if ( $new_input [ PostmanOptions::CLIENT_ID ] != $this->options->getClientId() || $new_input [ PostmanOptions::CLIENT_SECRET ] != $this->options->getClientSecret() || $new_input [ PostmanOptions::HOSTNAME ] != $this->options->getHostname() ) {
99
  $this->logger->debug( 'Recognized new Client ID' );
100
  // the user entered a new client id and we should destroy the stored auth token
117
 
118
  return $new_input;
119
  }
120
+
121
+ public function sanitizeString( $desc, $key, $input, &$new_input ) {
122
  if ( isset( $input [ $key ] ) ) {
123
  $this->logSanitize( $desc, $input [ $key ] );
124
  $new_input [ $key ] = trim( $input [ $key ] );
133
  * @param mixed $input
134
  * @param mixed $new_input
135
  */
136
+ public function sanitizePassword( $desc, $key, $input, &$new_input, $existingPassword ) {
137
  // WordPress calling Sanitize twice is a known issue
138
  // https://core.trac.wordpress.org/ticket/21989
139
  $action = PostmanSession::getInstance()->getAction();
Postman/PostmanLogFields.php ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class PostmanLogFields {
3
+
4
+ private $fields = array(
5
+ 'success' => 'sanitize_text_field',
6
+ 'from_header' => 'sanitize_text_field',
7
+ 'to_header' => 'sanitize_text_field',
8
+ 'cc_header' => 'sanitize_text_field',
9
+ 'bcc_header' => 'sanitize_text_field',
10
+ 'reply_to_header' => 'sanitize_text_field',
11
+ 'transport_uri' => 'sanitize_text_field',
12
+ 'original_to' => 'sanitize_text_field',
13
+ 'original_subject' => 'sanitize_text_field',
14
+ 'original_message' => null,
15
+ 'original_headers' => 'sanitize_text_field',
16
+ 'session_transcript' => 'sanitize_textarea_field',
17
+ );
18
+
19
+ private static $instance = null;
20
+
21
+ public static function get_instance() {
22
+ if ( ! self::$instance ) {
23
+ self::$instance = new static();
24
+ }
25
+
26
+ return self::$instance;
27
+ }
28
+
29
+ private function __construct()
30
+ {
31
+ $this->fields['original_message'] = array( $this, 'sanitize_message' );
32
+ }
33
+
34
+ public function get( $post_id ) {
35
+ $data = [];
36
+ foreach ( $this->fields as $key => $sanitize_callback ) {
37
+ $meta = get_post_meta( $post_id, $key, true );
38
+ $data[$key][] = $this->maybe_json( $meta );
39
+ }
40
+
41
+ return $data;
42
+ }
43
+
44
+ public function update( $post_id, $key, $value ) {
45
+ $sanitized = $this->sanitize( $key, $value );
46
+ $encode = $this->encode( $sanitized );
47
+
48
+ update_post_meta( $post_id, $key, $encode );
49
+ }
50
+
51
+ private function maybe_json( $json ) {
52
+ if ( $this->isJson( $json ) ) {
53
+ return implode( ',', json_decode( $json, true ) );
54
+ }
55
+
56
+ // Fallback
57
+ return maybe_unserialize( $json );
58
+ }
59
+
60
+ private function isJson($string) {
61
+ $result = json_decode($string, true);
62
+ $error = json_last_error();
63
+ return ( $error == JSON_ERROR_NONE && ! is_null($result) && $result != $string );
64
+ }
65
+
66
+ private function sanitize( $key, $value ) {
67
+ $callback = is_array( $value ) ? 'array_map' : 'call_user_func';
68
+
69
+ return $callback( $this->fields[$key], $value );
70
+ }
71
+
72
+ private function sanitize_message( $message ) {
73
+ $allowed_tags = wp_kses_allowed_html( 'post' );
74
+ $allowed_tags['style'] = array();
75
+
76
+ return wp_kses( $message, $allowed_tags );
77
+ }
78
+
79
+ private function encode( $value ) {
80
+ if ( is_array( $value ) ) {
81
+ return wp_json_encode( $value );
82
+ }
83
+
84
+ return $value;
85
+ }
86
+ }
Postman/PostmanUtils.php CHANGED
@@ -345,6 +345,15 @@ class PostmanUtils {
345
  if ( ! isset( PostmanUtils::$emailValidator ) ) {
346
  PostmanUtils::$emailValidator = new Postman_Zend_Validate_EmailAddress();
347
  }
 
 
 
 
 
 
 
 
 
348
  return PostmanUtils::$emailValidator->isValid( $email );
349
  }
350
 
345
  if ( ! isset( PostmanUtils::$emailValidator ) ) {
346
  PostmanUtils::$emailValidator = new Postman_Zend_Validate_EmailAddress();
347
  }
348
+ if ( strpos( $email, ',' ) !== false ) {
349
+ $emails = explode(',', $email);
350
+ $result = [];
351
+ foreach ( $emails as $email ) {
352
+ $result[] = PostmanUtils::$emailValidator->isValid( $email );
353
+ }
354
+
355
+ return ! in_array(false, $result );
356
+ }
357
  return PostmanUtils::$emailValidator->isValid( $email );
358
  }
359
 
Postman/PostmanViewController.php CHANGED
@@ -121,7 +121,7 @@ if ( ! class_exists( 'PostmanViewController' ) ) {
121
  }
122
  function enqueueHomeScreenStylesheet() {
123
  wp_enqueue_style( PostmanViewController::POSTMAN_STYLE );
124
- wp_enqueue_script( 'postman_script' );
125
  }
126
 
127
  /**
121
  }
122
  function enqueueHomeScreenStylesheet() {
123
  wp_enqueue_style( PostmanViewController::POSTMAN_STYLE );
124
+ wp_enqueue_script( PostmanViewController::POSTMAN_SCRIPT );
125
  }
126
 
127
  /**
postman-smtp.php CHANGED
@@ -6,7 +6,7 @@ if ( ! defined( 'ABSPATH' ) ) {
6
  * Plugin Name: Post SMTP
7
  * Plugin URI: https://wordpress.org/plugins/post-smtp/
8
  * Description: Email not reliable? Post SMTP is the first and only WordPress SMTP plugin to implement OAuth 2.0 for Gmail, Hotmail and Yahoo Mail. Setup is a breeze with the Configuration Wizard and integrated Port Tester. Enjoy worry-free delivery even if your password changes!
9
- * Version: 2.0.3
10
  * Author: Yehuda Hassine
11
  * Text Domain: post-smtp
12
  * Author URI: https://postmansmtp.com
@@ -44,7 +44,7 @@ if ( ! defined( 'ABSPATH' ) ) {
44
  define( 'POST_BASE', __FILE__ );
45
  define( 'POST_PATH', __DIR__ );
46
  define( 'POST_URL', plugins_url('', POST_BASE ) );
47
- define( 'POST_SMTP_VER', '2.0.3' );
48
 
49
  $postman_smtp_exist = in_array( 'postman-smtp/postman-smtp.php', (array) get_option( 'active_plugins', array() ) );
50
  $required_php_version = version_compare( PHP_VERSION, '5.6.0', '<' );
6
  * Plugin Name: Post SMTP
7
  * Plugin URI: https://wordpress.org/plugins/post-smtp/
8
  * Description: Email not reliable? Post SMTP is the first and only WordPress SMTP plugin to implement OAuth 2.0 for Gmail, Hotmail and Yahoo Mail. Setup is a breeze with the Configuration Wizard and integrated Port Tester. Enjoy worry-free delivery even if your password changes!
9
+ * Version: 2.0.4
10
  * Author: Yehuda Hassine
11
  * Text Domain: post-smtp
12
  * Author URI: https://postmansmtp.com
44
  define( 'POST_BASE', __FILE__ );
45
  define( 'POST_PATH', __DIR__ );
46
  define( 'POST_URL', plugins_url('', POST_BASE ) );
47
+ define( 'POST_SMTP_VER', '2.0.4' );
48
 
49
  $postman_smtp_exist = in_array( 'postman-smtp/postman-smtp.php', (array) get_option( 'active_plugins', array() ) );
50
  $required_php_version = version_compare( PHP_VERSION, '5.6.0', '<' );
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=yehuda@m
4
  Tags: postman smtp, postman, smtp, email, mail, mailer, email log, oauth2, gmail, google apps, hotmail, yahoo, mandrill api, sendgrid api, elastic email, office365, mailgun
5
  Requires at least: 3.9
6
  Tested up to: 5.2.2
7
- Stable tag: 2.0.3
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -12,8 +12,8 @@ Send, log and troubleshoot your Outgoing Email easily. Supports everything: SMTP
12
 
13
  == Description ==
14
 
15
- = Version 2.0.3 released - Security Fix =
16
- I fixed a few security issues - I still need to fix one more thing (minor), so another version bump will coming soon.
17
 
18
  = The Only SMTP plugin with chrome Notifications =
19
  Get notified if your emails are failing inside your Chrome browser. [Download here](https://chrome.google.com/webstore/detail/post-smtp-notifications/npklmbkpbknkmbohdbpikeidiaekjoch?hl=en-US)
@@ -289,6 +289,9 @@ To avoid being flagged as spam, you need to prove your email isn't forged. On a
289
 
290
  == Changelog ==
291
 
 
 
 
292
  = 2.0.3 - 2019-08-21
293
  * Fixed: A few security issues.
294
 
4
  Tags: postman smtp, postman, smtp, email, mail, mailer, email log, oauth2, gmail, google apps, hotmail, yahoo, mandrill api, sendgrid api, elastic email, office365, mailgun
5
  Requires at least: 3.9
6
  Tested up to: 5.2.2
7
+ Stable tag: 2.0.4
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
12
 
13
  == Description ==
14
 
15
+ = Version 2.0.4 released - The plugin is more secure =
16
+ Final fixes to make it the best and secure mailer plugin for WordPress
17
 
18
  = The Only SMTP plugin with chrome Notifications =
19
  Get notified if your emails are failing inside your Chrome browser. [Download here](https://chrome.google.com/webstore/detail/post-smtp-notifications/npklmbkpbknkmbohdbpikeidiaekjoch?hl=en-US)
289
 
290
  == Changelog ==
291
 
292
+ = 2.0.4 - 2019-08-27
293
+ * Updated: More security.
294
+
295
  = 2.0.3 - 2019-08-21
296
  * Fixed: A few security issues.
297