File manager - Edit - /home/palg2351/public_html/klanaobsesiindonesia.com/wp-includes/Text/Diff/Engine/mailer.tar
Back
outlook/outlook.php 0000644 00000022316 15173067213 0010456 0 ustar 00 <?php /** * Class GOSMTP_Mailer_Outlook. * * @since 1.0.0 */ namespace GOSMTP\Mailer\Outlook; use GOSMTP\Mailer\Loader; class Outlook extends Loader{ var $title = 'Outlook'; var $mailer = 'outlook'; var $url = 'https://graph.microsoft.com/v1.0/me/sendMail'; public function send(){ global $phpmailer; $phpmailer->isMail(); $phpmailer->Encoding = 'base64'; if ($phpmailer->preSend()) { $response = $this->postSend(); return $this->handle_response( $response ); } return $this->handle_response(new \WP_Error(400, 'Unable to send mail for some reason!', [])); } public function postSend(){ global $phpmailer; try{ $access_token = $this->getAccessToken($this->getMailerOption()); if(is_wp_error($access_token)){ return $access_token->get_error_message(); } $mime = chunk_split(base64_encode($phpmailer->getSentMIMEMessage()), 76, "\n"); $params = array( 'method' => 'POST', 'headers' => [ 'Authorization' => 'Bearer '. $access_token, 'Content-Type' => 'text/plain' ], 'body' => $mime ); $response = wp_remote_request($this->url, $params); if(is_wp_error($response)){ $return_response = new \WP_Error($response->get_error_code(), $response->get_error_message(), $response->get_error_messages()); }else{ $resp_body = wp_remote_retrieve_body($response); $resp_code = wp_remote_retrieve_response_code($response); $resp_body = \json_decode($resp_body, true); if(202 == $resp_code){ $msgId = isset( $response['headers']['request-id'] ) ? $response['headers']['request-id'] : ''; $status = __('Email sent successfully'); $return_response = [ 'status' => true, 'code' => $resp_code, 'messageId' => $msgId, 'message' => $status ]; }else{ $err_code = $resp_code; $error_text = ['']; if(!empty( $resp_body['error']) && is_array($resp_body['error'])){ $message = $resp_body['error']['message']; $code = !empty( $resp_body['error']['code'] ) ? $resp_body['error']['code'] : ''; $desc = ''; if($code === 'ErrorAccessDenied'){ $desc = esc_html__( 'Note: This issue can also be caused by exceeding the total message size limit. If you are using large attachments, please remove the existing Outlook Mailer OAuth connection in WP Mail SMTP settings and reconnect it. We recently added support for large attachments, but oAuth re-connection is required.'); } $error_text[] = $this->message_formatting( $message, $code, $desc ); }else{ $error_text[] = $this->get_response_error_message($response); } $error_msg = implode( '\r\n', array_map( 'esc_textarea', array_filter( $error_text ) ) ); $return_response = new \WP_Error($err_code, $error_msg, $resp_body); } } }catch(\Exception $e){ $return_response = new \WP_Error(423, $e->getMessage(), []); } return $return_response; } public function getRedirectUrl($query = ''){ // TODO check and change this return admin_url().'admin.php?page=gosmtp'.$query; } private function getAccessToken($options){ $accessToken = $options['access_token']; // check if expired or will be expired in 300 seconds if( ($options['expire_stamp'] - 300) < time()){ $api = new \GOSMTP\mailer\outlook\Auth($options['client_id'], $options['client_secret']); $tokens = $api->sendTokenRequest('refresh_token', [ 'refresh_token' => $options['refresh_token'] ]); if(is_wp_error($tokens)) { return false; } $this->saveNewTokens($options, $tokens); $accessToken = $tokens['access_token']; } return $accessToken; } private function saveNewTokens($data, $tokens){ if (empty($tokens['access_token']) || empty($tokens['refresh_token'])) { return false; } $this->update_option('access_token', $tokens['access_token'], $this->mailer); $this->update_option('refresh_token', $tokens['refresh_token'], $this->mailer); $this->update_option('expire_stamp', $tokens['expires_in'] + time(), $this->mailer); } public function load_field(){ $this->outlook_init(); $client_id = $this->getOption('client_id', $this->mailer); $client_secret = $this->getOption('client_secret', $this->mailer); $access_token = $this->getOption('access_token', $this->mailer); $refresh_token = $this->getOption('refresh_token', $this->mailer); $mail_type = $this->getOption('mail_type', $this->mailer); $activate = !empty($client_id) && !empty($client_secret) && empty($access_token) && empty($refresh_token); $deactivate = !empty($refresh_token) && !empty($access_token) && $this->mailer == $mail_type; $readonly = $deactivate ? 'readonly' : ''; $state = ($this->conn_id === 0 ? '' : '-'.$this->conn_id); $api = new \GOSMTP\mailer\outlook\Auth($client_id, $client_secret, $state); $fields = array( 'client_id' => array( 'title' => __('Application Client ID'), 'type' => 'text', 'attr' => $readonly, ), 'client_secret' => array( 'title' => __('Application Client Secret'), 'type' => 'password', 'attr' => $readonly, 'desc' => __( 'Follow this link to get a Application Client Secret from Outlook: <a href="https://learn.microsoft.com/en-us/azure/industry/training-services/microsoft-community-training/frequently-asked-questions/generate-new-clientsecret-link-to-key-vault" target="_blank">Application Client Secret.</a>' ), ), 'redirect_uri' => array( 'title' => __('Outlook Callback URL'), 'type' => 'copy', 'id' => 'outlook_redirect_uri', 'attr'=>'readonly', 'default' => $api->getRedirectUrl(), 'desc' => __('Use this URL to your APP as Redirect URI.') ) ); if($activate){ $fields['get_access_token'] = array( 'title' => __('Get Access Token'), 'type' => 'button', 'class'=>'access_token', 'default' => __('Authenticate with outlook/Office365 & Get Access Token'), 'href' => $api->getAuthUrl(), 'attr' => 'data-field=auth', ); }elseif($deactivate){ $fields['get_access_token'] = array( 'title' => __('Deactivate Access Token'), 'type' => 'button', 'class'=>'deactivate_token', 'default' => 'Deactivate Access Token', 'href' => $this->getRedirectUrl().($this->conn_id !== 0 ? '&type=edit&conn_id='.$this->conn_id.'&act=deactivate_token#gosmtp-connections-settings' : '&act=deactivate_token'), 'attr' => 'data-field=auth', ); }else{ $fields['get_access_token'] = array( 'title' => __('Get Access Token'), 'type' => 'notice', 'default' => __('You need to save settings with Client ID and Client Secret before you can proceed.'), ); } return $fields; } // Generate access token and refresh token and update in data base. public function set_token(){ $errors = []; $options = $this->getMailerOption(); if(empty($options['access_token']) && !empty($options['auth_token'])){ $api = new \GOSMTP\mailer\outlook\Auth($options['client_id'], $options['client_secret']); $tokens = $api->generateToken($options['auth_token']); if(is_wp_error($tokens) || (is_array($tokens) && isset($tokens['error']))) { $err = is_wp_error($tokens) ? $tokens->get_error_message() : __('Mailer Authentication failed!'); return new \WP_Error(423, $err); } $this->saveNewTokens($options, $tokens); }elseif(!$authToken && !$accessToken){ return new \WP_Error(423, __('Please Provide Auth Token.', 'GOSMTP')); } return true; } public function outlook_init(){ $options = $this->getMailerOption(); // Update auth URl when user succesfull regirect our page if( empty($options['access_token']) && empty($options['refresh_token']) && isset( $_GET['auth_code'] ) && isset( $_GET['auth'] ) && $this->mailer == $_GET['auth'] && strlen($this->conn_id) > 0 ){ if( !empty(gosmtp_optget('conn_id')) && $this->conn_id === 0 ){ return; } $auth_code = gosmtp_optget('auth_code'); $this->update_option('auth_token', $auth_code, $this->mailer); $resp = ''; $set_token = $this->set_token(); if(is_wp_error($set_token)){ $resp = $set_token->get_error_message(); }else{ $resp = __('Mailer successfully configured!'); } $query = ''; if( !is_numeric($this->conn_id) ){ $query = '&type=edit&conn_id='.$this->conn_id.$query.'#gosmtp-connections-settings'; } echo '<script> alert("'.$resp.'"); var url = "'.$this->getRedirectUrl($query).'"; history.pushState({urlPath:url},"",url); </script>'; } // Delete all the tokens or expire stamp when user click deactivate access token if(isset($_GET['act']) && $_GET['act'] == 'deactivate_token'){ if(!empty(gosmtp_optget('conn_id')) && $this->conn_id === 0){ return; } $this->delete_option('refresh_token', $this->mailer); $this->delete_option('expire_stamp', $this->mailer); $this->delete_option('expires_in', $this->mailer); $this->delete_option('version', $this->mailer); $this->delete_option('access_token', $this->mailer); $query = ''; if(!is_numeric($this->conn_id)){ $query = '&type=edit&conn_id='.$this->conn_id.$query.'#gosmtp-connections-settings'; } if(isset($_GET['conn_id'])){ echo '<script> var url = "'.$this->getRedirectUrl($query).'"; history.pushState({urlPath:url},"",url); </script>'; } } } } outlook/auth.php 0000644 00000015056 15173067213 0007726 0 ustar 00 <?php namespace GOSMTP\mailer\outlook; class Auth{ private $clientId; private $clientSecret; private $options; private $state; private $accessTokenMethod = 'POST'; public function __construct($clientId = '', $clientSecret = '', $state = ''){ $this->clientId = $clientId; $this->clientSecret = $clientSecret; $this->state = $state; //$this->assertRequiredOptions($this->getConfig()); $this->options = $this->getConfig(); } public function getAuthUrl(){ return $this->getAuthorizationUrl(); } public function generateToken($authCode){ return $this->sendTokenRequest('authorization_code', [ 'code' => $authCode ]); } public function sendTokenRequest($type, $params){ try { $tokens = $this->getAccessToken($type, $params); return $tokens; } catch (\Exception $exception) { return new \WP_Error(423, $exception->getMessage()); } } public function getRedirectUrl(){ return rest_url('gosmtp-smtp/outlook_callback'); } private function getConfig(){ return array( 'clientId' => $this->clientId, 'clientSecret' => $this->clientSecret, 'redirectUri' => $this->getRedirectUrl(), 'urlAuthorize' => 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize', 'urlAccessToken' => 'https://login.microsoftonline.com/common/oauth2/v2.0/token', 'urlResourceOwnerDetails' => '', 'scopes' => 'offline_access user.read Mail.Send' ); } public function getAuthorizationUrl($options = []){ $base = $this->options['urlAuthorize']; $params = $this->getAuthorizationParameters($options); $query = $this->getAuthorizationQuery($params); return $this->appendQuery($base, $query); } private function getAuthorizationParameters($options){ if(empty($options['state'])){ $options['state'] = $this->getRandomState().$this->state; update_option('_gosmtp_last_generated_state', $options['state']); } if(empty($options['scope'])){ $options['scope'] = $this->options['scopes']; } $options += [ 'response_type' => 'code', 'approval_prompt' => 'auto' ]; if(is_array($options['scope'])){ $separator = ','; $options['scope'] = implode($separator, $options['scope']); } // Store the state as it may need to be accessed later on. $this->options['state'] = $options['state']; // Business code layer might set a different redirect_uri parameter // depending on the context, leave it as-is if(!isset($options['redirect_uri'])){ $options['redirect_uri'] = $this->options['redirectUri']; } $options['client_id'] = $this->options['clientId']; return $options; } /** * Appends a query string to a URL. * * @param string $url The URL to append the query to * @param string $query The HTTP query string * @return string The resulting URL */ protected function appendQuery($url, $query){ $query = trim($query, '?&'); if($query){ $glue = strstr($url, '?') === false ? '?' : '&'; return $url . $glue . $query; } return $url; } /** * Builds the authorization URL's query string. * * @param array $params Query parameters * @return string Query string */ protected function getAuthorizationQuery(array $params){ return $this->buildQueryString($params); } /** * Build a query string from an array. * * @param array $params * * @return string */ protected function buildQueryString(array $params){ return http_build_query($params, null, '&', \PHP_QUERY_RFC3986); } /** * Verifies that all required options have been passed. * * @param array $options * @return void * @throws \InvalidArgumentException */ private function assertRequiredOptions(array $options){ $missing = array_diff_key(array_flip($this->getRequiredOptions()), $options); if (!empty($missing)) { throw new \InvalidArgumentException( 'Required options not defined: ' . implode(', ', array_keys($missing)) ); } } /** * Returns all options that are required. * * @return array */ protected function getRequiredOptions(){ return [ 'urlAuthorize', 'urlAccessToken', 'urlResourceOwnerDetails', ]; } /** * Returns a new random string to use as the state parameter in an * authorization flow. * * @param int $length Length of the random string to be generated. * @return string */ protected function getRandomState($length = 32){ // Converting bytes to hex will always double length. Hence, we can reduce // the amount of bytes by half to produce the correct length. $state = bin2hex(random_bytes($length / 2)); update_option('_gosmtp_last_generated_state', $state); return $state; } /** * Requests an access token using a specified grant and option set. * * @param mixed $grant * @param array $options * @throws \Exception * @return array tokens */ public function getAccessToken($grant, array $options = []){ $params = [ 'client_id' => $this->options['clientId'], 'client_secret' => $this->options['clientSecret'], 'redirect_uri' => $this->options['redirectUri'], 'grant_type' => $grant, ]; $params += $options; $requestData = $this->getAccessTokenRequestDetails($params); $response = wp_remote_request($requestData['url'], $requestData['params']); if(is_wp_error($response)) { throw new \Exception( $response->get_error_message() ); } $responseBody = wp_remote_retrieve_body($response); if(false === is_array($response)){ throw new \Exception( 'Invalid response received from Authorization Server. Expected JSON.' ); } if(empty(['access_token'])){ throw new \Exception( 'Invalid response received from Authorization Server.' ); } return \json_decode($responseBody, true); } /** * Returns a prepared request for requesting an access token. * * @param array $params Query string parameters * @return array $requestDetails */ protected function getAccessTokenRequestDetails($params){ $method = $this->accessTokenMethod; $url = $this->getAccessTokenUrl($params); $options = $this->buildQueryString($params); return [ 'url' => $url, 'params' => [ 'method' => $method, 'body' => $options, 'headers' => [ 'content-type' => 'application/x-www-form-urlencoded' ] ] ]; } /** * Returns the full URL to use when requesting an access token. * * @param array $params Query parameters * @return string */ protected function getAccessTokenUrl($params){ $url = $this->options['urlAccessToken']; if($this->accessTokenMethod === 'GET'){ $query = $this->getAccessTokenQuery($params); return $this->appendQuery($url, $query); } return $url; } protected function getAccessTokenQuery(array $params){ return $this->buildQueryString($params); } } smtp2go.php 0000644 00000012517 15173067213 0006663 0 ustar 00 <?php /** * Class GOSMTP_Mailer_SMTP2Go. * * @since 1.0.0 */ namespace GoSMTP\Mailer; use GOSMTP\Mailer\Loader; class SMTP2Go extends Loader{ var $title = 'SMTP2Go'; var $mailer = 'smtp2go'; var $url = 'https://api.smtp2go.com/v3/email/send'; public function send(){ global $phpmailer; if($phpmailer->preSend()){ $response = $this->postSend(); return $this->handle_response($response); } return $this->handle_response(new \WP_Error(400, 'Unable to send mail for some reason!', [])); } protected function postSend(){ global $phpmailer; try{ $api_key = $this->getOption('api_key', $this->mailer); if(empty($api_key)){ return new \WP_Error(401, 'SMTP2Go API Key is missing.'); } // SMTP2Go requires subject to be passed $subject = $phpmailer->Subject; if(empty($subject)){ $subject = 'Mail sent from: '. site_url(); } $from = $phpmailer->From; $fromName = $phpmailer->FromName; // Prepare SMTP2Go v4 API JSON Payload $payload = [ 'sender' => $fromName. '<' .$from. '>', 'to' => $this->filterRecipientsArray($phpmailer->getToAddresses()), 'cc' => $this->filterRecipientsArray($phpmailer->getCcAddresses()), 'bcc' => $this->filterRecipientsArray($phpmailer->getBccAddresses()), 'subject' => $subject, 'text_body' => '', 'html_body' => '', 'attachments' => $this->getAttachments() ]; $body_text = $phpmailer->AltBody; $body_html = $phpmailer->Body; if(!empty($body_text)){ $payload['text_body'] = $body_text; } if(!empty($body_html)){ $payload['html_body'] = $body_html; } $params = [ 'method' => 'POST', 'headers' => $this->getRequestHeaders(), 'body' => wp_json_encode($payload) ]; $response = wp_safe_remote_request($this->url, $params); if(is_wp_error($response)){ return new \WP_Error($response->get_error_code(), $response->get_error_message(), $response->get_error_messages()); } else{ $resp_body = wp_remote_retrieve_body($response); $resp_code = wp_remote_retrieve_response_code($response); $resp_body = \json_decode($resp_body, true); if(200 === $resp_code){ $msgId = isset($resp_body['data']['email_id']) ? $resp_body['data']['email_id'] : ''; $status = 'Email sent successfully'; $return_response = [ 'status' => true, 'code' => $resp_code, 'messageId' => $msgId, 'message' => $status ]; } else{ $err_code = $resp_code; $error_text = ['']; if(!empty($resp_body['Error']) && is_array($resp_body['Error'])){ $message = $resp_body['Error']; $code = isset($resp_body['Code']) ? $resp_body['Code'] : ''; $error_text[] = $this->message_formatting($message, $code); } else{ $error_text[] = $this->get_response_error_message($response); } $error_msg = implode('\r\n', array_map('esc_textarea', array_filter($error_text))); $return_response = new \WP_Error($err_code, $error_msg, $resp_body); } } } catch(\Exception $e){ return new \WP_Error(423, $e->getMessage(), []); } return $return_response; } protected function getRequestHeaders(){ return [ 'X-Smtp2go-Api-Key' => $this->getOption('api_key', $this->mailer), 'Content-Type' => 'application/json', 'Accept' => 'application/json' ]; } protected function getAttachments(){ global $phpmailer; $attachments_raw = $phpmailer->getAttachments(); $attachments = []; if(!empty($attachments_raw)){ // Handles multiple filenames /*if(!is_array($attachments_raw)){ $attArray = explode(PHP_EOL, $attachments_raw); } else{ $attArray = $attachments_raw; }*/ foreach($attachments_raw as $attachment){ $file_path = $attachment[0]; if(file_exists($file_path) && is_file($file_path) && is_readable($file_path)){ $file_content = file_get_contents($file_path); if(empty($file_content)){ continue; } $attachments[] = [ 'filename' => basename($file_path), 'mimetype' => $this->determineMimeContentType($file_path), 'fileblob' => base64_encode($file_content) ]; } } } return $attachments; } protected function filterRecipientsArray($args){ $recipients = []; foreach($args as $key => $recip){ $recip = array_filter($recip); if(empty($recip) || ! filter_var($recip[0], FILTER_VALIDATE_EMAIL)){ continue; } $recipients[] = $recip[0]; } return $recipients; } protected function determineMimeContentType($filename){ if(function_exists('mime_content_type')){ return mime_content_type($filename); } elseif(function_exists('finfo_open')){ $finfo = finfo_open(FILEINFO_MIME_TYPE); $mime_type = finfo_file($finfo, $filename); finfo_close($finfo); return $mime_type; } return 'application/octet-stream'; } public function load_field(){ $options = $this->getMailerOption(); $fields = [ 'api_key' => [ 'title' => __('API Key', 'gosmtp-pro'), 'type' => 'password', 'desc' => __('Follow this link to get an API Key from SMTP2Go: <a href="https://app-us.smtp2go.com/sending/apikeys/" target="_blank">Get API Key.</a>', 'gosmtp-pro'), ] ]; return $fields; } } elasticemail.php 0000644 00000013545 15173067213 0007726 0 ustar 00 <?php /** * Class GOSMTP_Mailer_ElasticEmail. * * @since 1.0.0 */ namespace GOSMTP\Mailer; use GOSMTP\Mailer\Loader; class ElasticEmail extends Loader{ var $title = 'Elastic Email'; var $mailer = 'elasticemail'; var $url = 'https://api.elasticemail.com/v4/emails/transactional'; public function send(){ global $phpmailer; if($phpmailer->preSend()){ $response = $this->postSend(); return $this->handle_response($response); } return $this->handle_response(new \WP_Error(400, 'Unable to send mail for some reason!', [])); } protected function postSend(){ global $phpmailer; try{ $api_key = $this->getOption('api_key', $this->mailer); if(empty($api_key)){ return new \WP_Error(401, 'Elastic Email API Key is missing.'); } $subject = $phpmailer->Subject; $from = $phpmailer->From; $fromName = $phpmailer->FromName; // Prepare Elastic Email v4 API JSON Payload $payload = [ 'Recipients' => $this->getRecipients(), 'Content' => [ 'From' => $fromName. '<' .$from. '>', 'EnvelopeFrom' => $fromName. '<' .$from. '>', 'Subject' => $subject, 'Body' => [], 'Attachments' => $this->getAttachments() ] ]; if($replyTo = $this->filterRecipientsArray($phpmailer->getReplyToAddresses())){ $payload['Content']['ReplyTo'] = $replyTo[0]; } $body_content = $phpmailer->Body; if(!empty($body_content)){ $body = []; $body['Content'] = $body_content; $body['ContentType'] = 'HTML'; if(!empty($phpmailer->ContentType) && $phpmailer->ContentType == 'text/plain'){ $body['ContentType'] = 'PlainText'; } $payload['Content']['Body'][] = $body; } if(!empty($phpmailer->XMailer)){ $payload['Content']['Headers'] = ['X-Mailer' => $phpmailer->XMailer]; } $params = [ 'method' => 'POST', 'headers' => $this->getRequestHeaders(), 'body' => wp_json_encode($payload) ]; $response = wp_safe_remote_request($this->url, $params); if (is_wp_error($response)){ return new \WP_Error($response->get_error_code(), $response->get_error_message(), $response->get_error_messages()); } else{ $resp_body = wp_remote_retrieve_body($response); $resp_code = wp_remote_retrieve_response_code($response); $resp_body = \json_decode($resp_body, true); if(200 === $resp_code){ $msgId = isset($resp_body['MessageID']) ? $resp_body['MessageID'] : ''; $status = 'Email sent successfully'; $return_response = [ 'status' => true, 'code' => $resp_code, 'messageId' => $msgId, 'message' => $status ]; } else{ $err_code = $resp_code; $error_text = ['']; if(!empty($resp_body['Error']) && is_array($resp_body['Error'])){ $message = $resp_body['Error']; $code = isset($resp_body['Code']) ? $resp_body['Code'] : ''; $error_text[] = $this->message_formatting($message, $code); } else{ $error_text[] = $this->get_response_error_message($response); } $error_msg = implode('\r\n', array_map('esc_textarea', array_filter($error_text))); $return_response = new \WP_Error($err_code, $error_msg, $resp_body); } } } catch(\Exception $e){ return new \WP_Error(423, $e->getMessage(), []); } return $return_response; } protected function getRequestHeaders(){ return [ 'X-ElasticEmail-ApiKey' => $this->getOption('api_key', $this->mailer), 'Content-Type' => 'application/json', 'Accept' => 'application/json' ]; } protected function getAttachments(){ global $phpmailer; $attachments_raw = $phpmailer->getAttachments(); $attachments = []; if(!empty($attachments_raw)){ // Handles multiple filenames /*if(!is_array($attachments_raw)){ $attArray = explode(PHP_EOL, $attachments_raw); } else{ $attArray = $attachments_raw; }*/ foreach($attachments_raw as $attachment){ $file_path = $attachment[0]; if(file_exists($file_path) && is_file($file_path) && is_readable($file_path)){ $file_content = file_get_contents($file_path); if(empty($file_content)){ continue; } $attachments[] = [ 'BinaryContent' => base64_encode($file_content), 'Name' => basename($file_path), 'ContentType' => $this->determineMimeContentType($file_path), 'Size' => filesize($file_path) ]; } } } return $attachments; } public function getRecipients(){ global $phpmailer; $recipients = [ 'To' => $this->filterRecipientsArray($phpmailer->getToAddresses()), 'CC' => $this->filterRecipientsArray($phpmailer->getCcAddresses()), 'BCC' => $this->filterRecipientsArray($phpmailer->getBccAddresses()), ]; return $recipients; } protected function filterRecipientsArray($args){ $recipients = []; foreach($args as $key => $recip){ $recip = array_filter($recip); if(empty($recip) || ! filter_var($recip[0], FILTER_VALIDATE_EMAIL)){ continue; } $recipients[] = $recip[0]; } return $recipients; } protected function determineMimeContentType($filename){ if(function_exists('mime_content_type')){ return mime_content_type($filename); } elseif(function_exists('finfo_open')){ $finfo = finfo_open(FILEINFO_MIME_TYPE); $mime_type = finfo_file($finfo, $filename); finfo_close($finfo); return $mime_type; } return 'application/octet-stream'; } public function load_field(){ $options = $this->getMailerOption(); $fields = [ 'api_key' => [ 'title' => __('API Key', 'gosmtp-pro'), 'type' => 'password', 'desc' => __('Follow this link to get an API Key from Elastic Email: <a href="https://app.elasticemail.com/api/settings/create-api" target="_blank">Get API Key</a>', 'gosmtp-pro'), ] ]; return $fields; } } amazonses/emailservicemessage.php 0000644 00000045752 15173067213 0013314 0 ustar 00 <?php namespace GOSMTP\mailer\amazonses; /** * EmailServiceMessage PHP class * * @link https://github.com/daniel-zahariev/php-aws-ses * @package AmazonEmailService * @version v0.9.1 */ final class EmailServiceMessage { // these are public for convenience only // these are not to be used outside of the EmailService class! public $to, $cc, $bcc, $replyto, $recipientsCharset; public $from, $returnpath; public $subject, $messagetext, $messagehtml; public $subjectCharset, $messageTextCharset, $messageHtmlCharset; public $attachments, $customHeaders, $configuration_set, $message_tags; public $is_clean, $raw_message; public $mime; public function __construct() { $this->to = array(); $this->cc = array(); $this->bcc = array(); $this->replyto = array(); $this->recipientsCharset = 'UTF-8'; $this->from = null; $this->returnpath = null; $this->subject = null; $this->messagetext = null; $this->messagehtml = null; $this->subjectCharset = 'UTF-8'; $this->messageTextCharset = 'UTF-8'; $this->messageHtmlCharset = 'UTF-8'; $this->attachments = array(); $this->customHeaders = array(); $this->configuration_set = null; $this->message_tags = array(); $this->is_clean = true; $this->raw_message = null; } /** * addTo, addCC, addBCC, and addReplyTo have the following behavior: * If a single address is passed, it is appended to the current list of addresses. * If an array of addresses is passed, that array is merged into the current list. * * @return EmailServiceMessage $this * @link http://docs.aws.amazon.com/ses/latest/APIReference/API_Destination.html */ public function addTo($to) { if (!is_array($to)) { $this->to[] = $to; } else { $this->to = array_unique(array_merge($this->to, $to)); } $this->is_clean = false; return $this; } /** * @return EmailServiceMessage $this */ public function setTo($to) { $this->to = (array) $to; $this->is_clean = false; return $this; } /** * Clear the To: email address(es) for the message * * @return EmailServiceMessage $this */ public function clearTo() { $this->to = array(); $this->is_clean = false; return $this; } /** * @return EmailServiceMessage $this * @see addTo() */ public function addCC($cc) { if (!is_array($cc)) { $this->cc[] = $cc; } else { $this->cc = array_merge($this->cc, $cc); } $this->is_clean = false; return $this; } /** * Clear the CC: email address(es) for the message * * @return EmailServiceMessage $this */ public function clearCC() { $this->cc = array(); $this->is_clean = false; return $this; } /** * @return EmailServiceMessage $this * @see addTo() */ public function addBCC($bcc) { if (!is_array($bcc)) { $this->bcc[] = $bcc; } else { $this->bcc = array_merge($this->bcc, $bcc); } $this->is_clean = false; return $this; } /** * Clear the BCC: email address(es) for the message * * @return EmailServiceMessage $this */ public function clearBCC() { $this->bcc = array(); $this->is_clean = false; return $this; } /** * @return EmailServiceMessage $this * @see addTo() */ public function addReplyTo($replyto) { if (!is_array($replyto)) { $this->replyto[] = $replyto; } else { $this->replyto = array_merge($this->replyto, $replyto); } $this->is_clean = false; return $this; } /** * Clear the Reply-To: email address(es) for the message * * @return EmailServiceMessage $this */ public function clearReplyTo() { $this->replyto = array(); $this->is_clean = false; return $this; } /** * Clear all of the message recipients in one go * * @return EmailServiceMessage $this * @uses clearTo() * @uses clearCC() * @uses clearBCC() * @uses clearReplyTo() */ public function clearRecipients() { $this->clearTo(); $this->clearCC(); $this->clearBCC(); $this->clearReplyTo(); $this->is_clean = false; return $this; } /** * @return EmailServiceMessage $this */ public function setFrom($from) { $this->from = $from; $this->is_clean = false; return $this; } /** * @return EmailServiceMessage $this */ public function setReturnPath($returnpath) { $this->returnpath = $returnpath; $this->is_clean = false; return $this; } /** * @return EmailServiceMessage $this */ public function setRecipientsCharset($charset) { $this->recipientsCharset = $charset; $this->is_clean = false; return $this; } /** * @return EmailServiceMessage $this */ public function setSubject($subject) { $this->subject = $subject; $this->is_clean = false; return $this; } /** * @return EmailServiceMessage $this */ public function setSubjectCharset($charset) { $this->subjectCharset = $charset; $this->is_clean = false; return $this; } /** * @return EmailServiceMessage $this * @link http://docs.aws.amazon.com/ses/latest/APIReference/API_Message.html */ public function setMessageFromString($text, $html = null) { $this->messagetext = $text; $this->messagehtml = $html; $this->is_clean = false; return $this; } /** * @return EmailServiceMessage $this */ public function setMessageFromFile($textfile, $htmlfile = null) { if (file_exists($textfile) && is_file($textfile) && is_readable($textfile)) { $this->messagetext = file_get_contents($textfile); } else { $this->messagetext = null; } if (file_exists($htmlfile) && is_file($htmlfile) && is_readable($htmlfile)) { $this->messagehtml = file_get_contents($htmlfile); } else { $this->messagehtml = null; } $this->is_clean = false; return $this; } /** * @return EmailServiceMessage $this */ public function setMessageFromURL($texturl, $htmlurl = null) { if ($texturl !== null) { $this->messagetext = file_get_contents($texturl); } else { $this->messagetext = null; } if ($htmlurl !== null) { $this->messagehtml = file_get_contents($htmlurl); } else { $this->messagehtml = null; } $this->is_clean = false; return $this; } /** * @return EmailServiceMessage $this */ public function setMessageCharset($textCharset, $htmlCharset = null) { $this->messageTextCharset = $textCharset; $this->messageHtmlCharset = $htmlCharset; $this->is_clean = false; return $this; } /** * @return EmailServiceMessage $this */ public function setConfigurationSet($configuration_set = null) { $this->configuration_set = $configuration_set; $this->is_clean = false; return $this; } /** * @return array $message_tags */ public function getMessageTags() { return $this->message_tags; } /** * @return null|mixed $message_tag */ public function getMessageTag($key) { return isset($this->message_tags[$key]) ? $this->message_tags[$key] : null; } /** * Add Message tag * * Both key and value can contain only ASCII letters (a-z, A-Z), numbers (0-9), underscores (_), or dashes (-) and be less than 256 characters. * * @param string $key * @param mixed $value * @return EmailServiceMessage $this * @link https://docs.aws.amazon.com/ses/latest/DeveloperGuide/event-publishing-send-email.html * @link https://docs.aws.amazon.com/ses/latest/APIReference/API_MessageTag.html */ public function setMessageTag($key, $value) { $this->message_tags[$key] = $value; $this->is_clean = false; return $this; } /** * @param string $key The key of the tag to be removed * @return EmailServiceMessage $this */ public function removeMessageTag($key) { unset($this->message_tags[$key]); $this->is_clean = false; return $this; } /** * @param array $message_tags * @return EmailServiceMessage $this */ public function setMessageTags($message_tags = array()) { $this->message_tags = array_merge($this->message_tags, $message_tags); $this->is_clean = false; return $this; } /** * @return EmailServiceMessage $this */ public function removeMessageTags() { $this->message_tags = array(); $this->is_clean = false; return $this; } /** * Add custom header - this works only with SendRawEmail * * @param string $header Your custom header * @return EmailServiceMessage $this * @link( Restrictions on headers, http://docs.aws.amazon.com/ses/latest/DeveloperGuide/header-fields.html) */ public function addCustomHeader($header) { $this->customHeaders[] = $header; $this->is_clean = false; return $this; } /** * Add email attachment by directly passing the content * * @param string $name The name of the file attachment as it will appear in the email * @param string $data The contents of the attachment file * @param string $mimeType Specify custom MIME type * @param string $contentId Content ID of the attachment for inclusion in the mail message * @param string $attachmentType Attachment type: attachment or inline * @return EmailServiceMessage $this */ public function addAttachmentFromData($name, $data, $mimeType = 'application/octet-stream', $contentId = null, $attachmentType = 'attachment') { $this->attachments[$name] = array( 'name' => $name, 'mimeType' => $mimeType, 'data' => $data, 'contentId' => $contentId, 'attachmentType' => ($attachmentType == 'inline' ? 'inline; filename="' . $name . '"' : $attachmentType), ); $this->is_clean = false; return $this; } /** * Add email attachment by passing file path * * @param string $name The name of the file attachment as it will appear in the email * @param string $path Path to the attachment file * @param string $mimeType Specify custom MIME type * @param string $contentId Content ID of the attachment for inclusion in the mail message * @param string $attachmentType Attachment type: attachment or inline * @return boolean Status of the operation */ public function addAttachmentFromFile($name, $path, $mimeType = 'application/octet-stream', $contentId = null, $attachmentType = 'attachment') { if (file_exists($path) && is_file($path) && is_readable($path)) { $this->addAttachmentFromData($name, file_get_contents($path), $mimeType, $contentId, $attachmentType); return true; } $this->is_clean = false; return false; } /** * Add email attachment by passing file path * * @param string $name The name of the file attachment as it will appear in the email * @param string $url URL to the attachment file * @param string $mimeType Specify custom MIME type * @param string $contentId Content ID of the attachment for inclusion in the mail message * @param string $attachmentType Attachment type: attachment or inline * @return boolean Status of the operation */ public function addAttachmentFromUrl($name, $url, $mimeType = 'application/octet-stream', $contentId = null, $attachmentType = 'attachment') { $data = file_get_contents($url); if ($data !== false) { $this->addAttachmentFromData($name, $data, $mimeType, $contentId, $attachmentType); return true; } $this->is_clean = false; return false; } /** * Get the existence of attached inline messages * * @return boolean */ public function hasInlineAttachments() { foreach ($this->attachments as $attachment) { if ($attachment['attachmentType'] != 'attachment') { return true; } } return false; } /** * Get the raw mail message * * @return string */ public function getRawMessage($encode = true) { if ($this->is_clean && !is_null($this->raw_message) && $encode) { return $this->raw_message; } $this->is_clean = true; $boundary = uniqid(rand(), true); $raw_message = count($this->customHeaders) > 0 ? join("\n", $this->customHeaders) . "\n" : ''; if (!empty($this->message_tags)) { $message_tags = array(); foreach ($this->message_tags as $key => $value) { $message_tags[] = "{$key}={$value}"; } $raw_message .= 'X-SES-MESSAGE-TAGS: ' . join(', ', $message_tags) . "\n"; } if (!is_null($this->configuration_set)) { $raw_message .= 'X-SES-CONFIGURATION-SET: ' . $this->configuration_set . "\n"; } $raw_message .= count($this->to) > 0 ? 'To: ' . $this->encodeRecipients($this->to) . "\n" : ''; $raw_message .= 'From: ' . $this->encodeRecipients($this->from) . "\n"; if (!empty($this->replyto)) { $raw_message .= 'Reply-To: ' . $this->encodeRecipients($this->replyto) . "\n"; } if (!empty($this->cc)) { $raw_message .= 'CC: ' . $this->encodeRecipients($this->cc) . "\n"; } if (!empty($this->bcc)) { $raw_message .= 'BCC: ' . $this->encodeRecipients($this->bcc) . "\n"; } if ($this->subject != null && strlen($this->subject) > 0) { $raw_message .= 'Subject: =?' . $this->subjectCharset . '?B?' . base64_encode($this->subject) . "?=\n"; } $raw_message .= 'MIME-Version: 1.0' . "\n"; $raw_message .= 'Content-type: ' . ($this->hasInlineAttachments() ? 'multipart/related' : 'Multipart/Mixed') . '; boundary="' . $boundary . '"' . "\n"; $raw_message .= "\n--{$boundary}\n"; $raw_message .= 'Content-type: Multipart/Alternative; boundary="alt-' . $boundary . '"' . "\n"; if ($this->messagetext != null && strlen($this->messagetext) > 0) { $charset = empty($this->messageTextCharset) ? '' : "; charset=\"{$this->messageTextCharset}\""; $raw_message .= "\n--alt-{$boundary}\n"; $raw_message .= 'Content-Type: text/plain' . $charset . "\n\n"; $raw_message .= $this->messagetext . "\n"; } if ($this->messagehtml != null && strlen($this->messagehtml) > 0) { $charset = empty($this->messageHtmlCharset) ? '' : "; charset=\"{$this->messageHtmlCharset}\""; $raw_message .= "\n--alt-{$boundary}\n"; $raw_message .= 'Content-Type: text/html' . $charset . "\n\n"; $raw_message .= $this->messagehtml . "\n"; } $raw_message .= "\n--alt-{$boundary}--\n"; foreach ($this->attachments as $attachment) { $raw_message .= "\n--{$boundary}\n"; $raw_message .= 'Content-Type: ' . $attachment['mimeType'] . '; name="' . $attachment['name'] . '"' . "\n"; $raw_message .= 'Content-Disposition: ' . $attachment['attachmentType'] . "\n"; if (!empty($attachment['contentId'])) { $raw_message .= 'Content-ID: ' . $attachment['contentId'] . '' . "\n"; } $raw_message .= 'Content-Transfer-Encoding: base64' . "\n"; $raw_message .= "\n" . chunk_split(base64_encode($attachment['data']), 76, "\n") . "\n"; } $raw_message .= "\n--{$boundary}--\n"; if (!$encode) { return $raw_message; } $this->raw_message = base64_encode($raw_message); return $this->raw_message; } /** * Encode recipient with the specified charset in `recipientsCharset` * * @return string Encoded recipients joined with comma */ public function encodeRecipients($recipient) { if (is_array($recipient)) { return join(', ', array_map(array($this, 'encodeRecipients'), $recipient)); } if (preg_match("/(.*)<(.*)>/", $recipient, $regs)) { $recipient = '=?' . $this->recipientsCharset . '?B?' . base64_encode($regs[1]) . '?= <' . $regs[2] . '>'; } return $recipient; } /** * Validates whether the message object has sufficient information to submit a request to SES. * * This does not guarantee the message will arrive, nor that the request will succeed; * instead, it makes sure that no required fields are missing. * * This is used internally before attempting a SendEmail or SendRawEmail request, * but it can be used outside of this file if verification is desired. * May be useful if e.g. the data is being populated from a form; developers can generally * use this function to verify completeness instead of writing custom logic. * * @return boolean */ public function validate() { // at least one destination is required if (count($this->to) == 0 && count($this->cc) == 0 && count($this->bcc) == 0) { return false; } // sender is required if ($this->from == null || strlen($this->from) == 0) { return false; } // subject is required if (($this->subject == null || strlen($this->subject) == 0)) { return false; } // message is required if ((empty($this->messagetext) || strlen((string) $this->messagetext) == 0) && (empty($this->messagehtml) || strlen((string) $this->messagehtml) == 0)) { return false; } return true; } } amazonses/emailservice.php 0000644 00000056721 15173067213 0011745 0 ustar 00 <?php namespace GOSMTP\mailer\amazonses; use GOSMTP\mailer\amazonses\EmailServiceRequest; /** * * Copyright (c) 2014, Daniel Zahariev. * Copyright (c) 2011, Dan Myers. * Parts copyright (c) 2008, Donovan Schonknecht. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * This is a modified BSD license (the third clause has been removed). * The BSD license may be found here: * http://www.opensource.org/licenses/bsd-license.php * * Amazon Simple Email Service is a trademark of Amazon.com, Inc. or its affiliates. * * EmailService is based on Donovan Schonknecht's Amazon S3 PHP class, found here: * http://undesigned.org.za/2007/10/22/amazon-s3-php-class * * @copyright 2014 Daniel Zahariev * @copyright 2011 Dan Myers * @copyright 2008 Donovan Schonknecht */ /** * EmailService PHP class * * @link https://github.com/daniel-zahariev/php-aws-ses * @package AmazonEmailService * @version v0.9.1 */ class EmailService { /** * @link(AWS SES regions, http://docs.aws.amazon.com/ses/latest/DeveloperGuide/regions.html) */ const AWS_US_EAST_1 = 'email.us-east-1.amazonaws.com'; const AWS_US_WEST_2 = 'email.us-west-2.amazonaws.com'; const AWS_EU_WEST1 = 'email.eu-west-1.amazonaws.com'; const REQUEST_SIGNATURE_V3 = 'v3'; const REQUEST_SIGNATURE_V4 = 'v4'; /** * AWS SES Target host of region */ protected $__host; /** * AWS SES Access key */ protected $__accessKey; /** * AWS Secret key */ protected $__secretKey; /** * Enable/disable */ protected $__trigger_errors; /** * Controls the reuse of CURL hander for sending a bulk of messages * @deprecated */ protected $__bulk_sending_mode = false; /** * Optionally reusable EmailServiceRequest instance */ protected $__ses_request = null; /** * Controls CURLOPT_SSL_VERIFYHOST setting for EmailServiceRequest's curl handler */ protected $__verifyHost = true; /** * Controls CURLOPT_SSL_VERIFYPEER setting for EmailServiceRequest's curl handler */ protected $__verifyPeer = true; /** * @var string HTTP Request signature version */ protected $__requestSignatureVersion; /** * Constructor * * @param string $accessKey Access key * @param string $secretKey Secret key * @param string $host Amazon Host through which to send the emails * @param boolean $trigger_errors Trigger PHP errors when AWS SES API returns an error * @param string $requestSignatureVersion Version of the request signature */ public function __construct($accessKey = null, $secretKey = null, $host = self::AWS_US_EAST_1, $trigger_errors = true, $requestSignatureVersion = self::REQUEST_SIGNATURE_V4) { if ($accessKey !== null && $secretKey !== null) { $this->setAuth($accessKey, $secretKey); } $this->__host = $host; $this->__trigger_errors = $trigger_errors; $this->__requestSignatureVersion = $requestSignatureVersion; } /** * Set the request signature version * * @param string $requestSignatureVersion * @return EmailService $this */ public function setRequestSignatureVersion($requestSignatureVersion) { $this->__requestSignatureVersion = $requestSignatureVersion; return $this; } /** * @return string */ public function getRequestSignatureVersion() { return $this->__requestSignatureVersion; } /** * Set AWS access key and secret key * * @param string $accessKey Access key * @param string $secretKey Secret key * @return EmailService $this */ public function setAuth($accessKey, $secretKey) { $this->__accessKey = $accessKey; $this->__secretKey = $secretKey; return $this; } /** * Set AWS Host * @param string $host AWS Host */ public function setHost($host = self::AWS_US_EAST_1) { $this->__host = $host; return $this; } /** * @deprecated */ public function enableVerifyHost($enable = true) { $this->__verifyHost = (bool)$enable; return $this; } /** * @deprecated */ public function enableVerifyPeer($enable = true) { $this->__verifyPeer = (bool)$enable; return $this; } /** * @deprecated */ public function verifyHost() { return $this->__verifyHost; } /** * @deprecated */ public function verifyPeer() { return $this->__verifyPeer; } /** * Get AWS target host * @return boolean */ public function getHost() { return $this->__host; } /** * Get AWS SES auth access key * @return string */ public function getAccessKey() { return $this->__accessKey; } /** * Get AWS SES auth secret key * @return string */ public function getSecretKey() { return $this->__secretKey; } /** * Get the verify peer CURL mode * @return boolean */ public function getVerifyPeer() { return $this->__verifyPeer; } /** * Get the verify host CURL mode * @return boolean */ public function getVerifyHost() { return $this->__verifyHost; } /** * Get bulk email sending mode * @return boolean * @deprecated */ public function getBulkMode() { return $this->__bulk_sending_mode; } /** * Enable/disable CURLOPT_SSL_VERIFYHOST for EmailServiceRequest's curl handler * verifyHost and verifyPeer determine whether curl verifies ssl certificates. * It may be necessary to disable these checks on certain systems. * These only have an effect if SSL is enabled. * * @param boolean $enable New status for the mode * @return EmailService $this */ public function setVerifyHost($enable = true) { $this->__verifyHost = (bool)$enable; return $this; } /** * Enable/disable CURLOPT_SSL_VERIFYPEER for EmailServiceRequest's curl handler * verifyHost and verifyPeer determine whether curl verifies ssl certificates. * It may be necessary to disable these checks on certain systems. * These only have an effect if SSL is enabled. * * @param boolean $enable New status for the mode * @return EmailService $this */ public function setVerifyPeer($enable = true) { $this->__verifyPeer = (bool)$enable; return $this; } /** * Enable/disable bulk email sending mode * * @param boolean $enable New status for the mode * @return EmailService $this * @deprecated */ public function setBulkMode($enable = true) { $this->__bulk_sending_mode = (bool)$enable; return $this; } /** * Lists the email addresses that have been verified and can be used as the 'From' address * * @return array An array containing two items: a list of verified email addresses, and the request id. */ public function listVerifiedEmailAddresses() { $ses_request = $this->getRequestHandler('GET'); $ses_request->setParameter('Action', 'ListIdentities'); $ses_response = $ses_request->getResponse(); if ($ses_response->error === false && $ses_response->code !== 200) { $ses_response->error = array('code' => $ses_response->code, 'message' => 'Unexpected HTTP status'); } if ($ses_response->error !== false) { $this->__triggerError('ListIdentities', $ses_response->error); return []; } $response = array(); if (!isset($ses_response->body)) { return $response; } $addresses = array(); foreach ($ses_response->body->ListIdentitiesResult->Identities->member as $address) { if(is_email($address)) { $addresses[] = (string)$address; } } $response['Addresses'] = $addresses; $response['RequestId'] = (string)$ses_response->body->ResponseMetadata->RequestId; return $response; } /** * Requests verification of the provided email address, so it can be used * as the 'From' address when sending emails through EmailService. * * After submitting this request, you should receive a verification email * from Amazon at the specified address containing instructions to follow. * * @param string $email The email address to get verified * @return array The request id for this request. */ public function verifyEmailAddress($email) { $ses_request = $this->getRequestHandler('POST'); $ses_request->setParameter('Action', 'VerifyEmailAddress'); $ses_request->setParameter('EmailAddress', $email); $ses_response = $ses_request->getResponse(); if ($ses_response->error === false && $ses_response->code !== 200) { $ses_response->error = array('code' => $ses_response->code, 'message' => 'Unexpected HTTP status'); } if ($ses_response->error !== false) { $this->__triggerError('verifyEmailAddress', $ses_response->error); return false; } $response['RequestId'] = (string)$ses_response->body->ResponseMetadata->RequestId; return $response; } /** * Removes the specified email address from the list of verified addresses. * * @param string $email The email address to remove * @return array The request id for this request. */ public function deleteVerifiedEmailAddress($email) { $ses_request = $this->getRequestHandler('DELETE'); $ses_request->setParameter('Action', 'DeleteVerifiedEmailAddress'); $ses_request->setParameter('EmailAddress', $email); $ses_response = $ses_request->getResponse(); if ($ses_response->error === false && $ses_response->code !== 200) { $ses_response->error = array('code' => $ses_response->code, 'message' => 'Unexpected HTTP status'); } if ($ses_response->error !== false) { $this->__triggerError('deleteVerifiedEmailAddress', $ses_response->error); return false; } $response['RequestId'] = (string)$ses_response->body->ResponseMetadata->RequestId; return $response; } /** * Retrieves information on the current activity limits for this account. * See http://docs.amazonwebservices.com/ses/latest/APIReference/API_GetSendQuota.html * * @return array An array containing information on this account's activity limits. */ public function getSendQuota() { $ses_request = $this->getRequestHandler('GET'); $ses_request->setParameter('Action', 'GetSendQuota'); $ses_response = $ses_request->getResponse(); if ($ses_response->error === false && $ses_response->code !== 200) { $ses_response->error = array('code' => $ses_response->code, 'message' => 'Unexpected HTTP status'); } if ($ses_response->error !== false) { $this->__triggerError('getSendQuota', $ses_response->error); return false; } $response = array(); if (!isset($ses_response->body)) { return $response; } $response['Max24HourSend'] = (string)$ses_response->body->GetSendQuotaResult->Max24HourSend; $response['MaxSendRate'] = (string)$ses_response->body->GetSendQuotaResult->MaxSendRate; $response['SentLast24Hours'] = (string)$ses_response->body->GetSendQuotaResult->SentLast24Hours; $response['RequestId'] = (string)$ses_response->body->ResponseMetadata->RequestId; return $response; } /** * Retrieves statistics for the last two weeks of activity on this account. * See http://docs.amazonwebservices.com/ses/latest/APIReference/API_GetSendStatistics.html * * @return array An array of activity statistics. Each array item covers a 15-minute period. */ public function getSendStatistics() { $ses_request = $this->getRequestHandler('GET'); $ses_request->setParameter('Action', 'GetSendStatistics'); $ses_response = $ses_request->getResponse(); if ($ses_response->error === false && $ses_response->code !== 200) { $ses_response->error = array('code' => $ses_response->code, 'message' => 'Unexpected HTTP status'); } if ($ses_response->error !== false) { $this->__triggerError('getSendStatistics', $ses_response->error); return false; } $response = array(); if (!isset($ses_response->body)) { return $response; } $datapoints = array(); foreach ($ses_response->body->GetSendStatisticsResult->SendDataPoints->member as $datapoint) { $p = array(); $p['Bounces'] = (string)$datapoint->Bounces; $p['Complaints'] = (string)$datapoint->Complaints; $p['DeliveryAttempts'] = (string)$datapoint->DeliveryAttempts; $p['Rejects'] = (string)$datapoint->Rejects; $p['Timestamp'] = (string)$datapoint->Timestamp; $datapoints[] = $p; } $response['SendDataPoints'] = $datapoints; $response['RequestId'] = (string)$ses_response->body->ResponseMetadata->RequestId; return $response; } /** * Given a EmailServiceMessage object, submits the message to the service for sending. * * @param EmailServiceMessage $sesMessage An instance of the message class * @param boolean $use_raw_request If this is true or there are attachments to the email `SendRawEmail` call will be used * @param boolean $trigger_error Optionally overwrite the class setting for triggering an error (with type check to true/false) * @return array An array containing the unique identifier for this message and a separate request id. * Returns false if the provided message is missing any required fields. * @link(AWS SES Response formats, http://docs.aws.amazon.com/ses/latest/DeveloperGuide/query-interface-responses.html) */ public function sendEmail($sesMessage, $use_raw_request = false, $trigger_error = null) { if (!$sesMessage->validate()) { $this->__triggerError('sendEmail', 'Message failed validation.'); return false; } $ses_request = $this->getRequestHandler('POST'); $action = !empty($sesMessage->attachments) || $use_raw_request ? 'SendRawEmail' : 'SendEmail'; $ses_request->setParameter('Action', $action); // Works with both calls if (!is_null($sesMessage->configuration_set)) { $ses_request->setParameter('ConfigurationSetName', $sesMessage->configuration_set); } if ($action == 'SendRawEmail') { // https://docs.aws.amazon.com/ses/latest/APIReference/API_SendRawEmail.html $ses_request->setParameter('RawMessage.Data', $sesMessage->mime); } else { $i = 1; foreach ($sesMessage->to as $to) { $ses_request->setParameter('Destination.ToAddresses.member.' . $i, $sesMessage->encodeRecipients($to)); $i++; } if (is_array($sesMessage->cc)) { $i = 1; foreach ($sesMessage->cc as $cc) { $ses_request->setParameter('Destination.CcAddresses.member.' . $i, $sesMessage->encodeRecipients($cc)); $i++; } } if (is_array($sesMessage->bcc)) { $i = 1; foreach ($sesMessage->bcc as $bcc) { $ses_request->setParameter('Destination.BccAddresses.member.' . $i, $sesMessage->encodeRecipients($bcc)); $i++; } } if (is_array($sesMessage->replyto)) { $i = 1; foreach ($sesMessage->replyto as $replyto) { $ses_request->setParameter('ReplyToAddresses.member.' . $i, $sesMessage->encodeRecipients($replyto)); $i++; } } $ses_request->setParameter('Source', $sesMessage->encodeRecipients($sesMessage->from)); if ($sesMessage->returnpath != null) { $ses_request->setParameter('ReturnPath', $sesMessage->returnpath); } if ($sesMessage->subject != null && strlen($sesMessage->subject) > 0) { $ses_request->setParameter('Message.Subject.Data', $sesMessage->subject); if ($sesMessage->subjectCharset != null && strlen($sesMessage->subjectCharset) > 0) { $ses_request->setParameter('Message.Subject.Charset', $sesMessage->subjectCharset); } } if ($sesMessage->messagetext != null && strlen($sesMessage->messagetext) > 0) { $ses_request->setParameter('Message.Body.Text.Data', $sesMessage->messagetext); if ($sesMessage->messageTextCharset != null && strlen($sesMessage->messageTextCharset) > 0) { $ses_request->setParameter('Message.Body.Text.Charset', $sesMessage->messageTextCharset); } } if ($sesMessage->messagehtml != null && strlen($sesMessage->messagehtml) > 0) { $ses_request->setParameter('Message.Body.Html.Data', $sesMessage->messagehtml); if ($sesMessage->messageHtmlCharset != null && strlen($sesMessage->messageHtmlCharset) > 0) { $ses_request->setParameter('Message.Body.Html.Charset', $sesMessage->messageHtmlCharset); } } $i = 1; foreach ($sesMessage->message_tags as $key => $value) { $ses_request->setParameter('Tags.member.' . $i . '.Name', $key); $ses_request->setParameter('Tags.member.' . $i . '.Value', $value); $i++; } } $ses_response = $ses_request->getResponse(); if ($ses_response->error === false && $ses_response->code !== 200) { $response = array( 'code' => $ses_response->code, 'error' => array('Error' => array('message' => 'Unexpected HTTP status')), ); return $response; } if ($ses_response->error !== false) { if (($this->__trigger_errors && ($trigger_error !== false)) || $trigger_error === true) { $this->__triggerError('sendEmail', $ses_response->error); return false; } return $ses_response; } $response = array( 'MessageId' => (string)$ses_response->body->{"{$action}Result"}->MessageId, 'RequestId' => (string)$ses_response->body->ResponseMetadata->RequestId, ); return $response; } public function sendRawEmail($sesMessage) { $ses_request = $this->getRequestHandler('POST'); $ses_request->setParameter('Action', 'SendRawEmail'); // https://docs.aws.amazon.com/ses/latest/APIReference/API_SendRawEmail.html $ses_request->setParameter('RawMessage.Data', $sesMessage); $ses_response = $ses_request->getResponse(); if (($ses_response->error === false && $ses_response->code !== 200) || $ses_response->error !== false) { return new \WP_Error($ses_response->code, $this->getErrorMessage('sendRawEmail', $ses_response->error), $ses_response->error); } return array( 'MessageId' => (string)$ses_response->body->SendRawEmailResult->MessageId, 'RequestId' => (string)$ses_response->body->ResponseMetadata->RequestId, ); } /** * Trigger an error message * * {@internal Used by member functions to output errors} * @param string $functionname The name of the function that failed * @param array $error Array containing error information * @return void */ public function __triggerError($functionname, $error) { trigger_error($this->getErrorMessage($functionname, $error), E_USER_WARNING); } public function getErrorMessage($functionname, $error) { if ($error == false) { return sprintf("EmailService::%s(): Encountered an error, but no description given", $functionname); } else if (isset($error['curl']) && $error['curl']) { return sprintf("EmailService::%s(): %s %s", $functionname, $error['code'], $error['message']); } else if (isset($error['Error'])) { $e = $error['Error']; return sprintf("EmailService::%s(): %s - %s: %s\nRequest Id: %s\n", $functionname, $e['Type'], $e['Code'], $e['Message'], $error['RequestId']); } return sprintf("EmailService::%s(): Encountered an error: %s", $functionname, $error); } /** * Set SES Request * * @param EmailServiceRequest $ses_request description * @return EmailService $this */ public function setRequestHandler(EmailServiceRequest $ses_request = null) { if (!is_null($ses_request)) { $ses_request->setSES($this); } $this->__ses_request = $ses_request; return $this; } /** * Get SES Request * * @param string $verb HTTP Verb: GET, POST, DELETE * @return EmailServiceRequest SES Request */ public function getRequestHandler($verb) { if (empty($this->__ses_request)) { $this->__ses_request = new EmailServiceRequest($this, $verb); } else { $this->__ses_request->setVerb($verb); } return $this->__ses_request; } } amazonses/emailservicerequest.php 0000644 00000025556 15173067213 0013360 0 ustar 00 <?php namespace GOSMTP\mailer\amazonses; /** * EmailServiceRequest PHP class * * @link https://github.com/daniel-zahariev/php-aws-ses * @package AmazonEmailService * @version v0.9.1 */ class EmailServiceRequest { private $ses, $verb, $parameters = array(); // CURL request handler that can be reused protected $curl_handler = null; // Holds the response from calling AWS's API protected $response; // public static $curlOptions = array(); /** * Constructor * * @param EmailService $ses The EmailService object making this request * @param string $verb HTTP verb * @return void */ public function __construct(EmailService $ses = null, $verb = 'GET') { $this->ses = $ses; $this->verb = $verb; $this->response = (object) array('body' => '', 'code' => 0, 'error' => false); } /** * Set SES class * * @param EmailService $ses * @return EmailServiceRequest $this */ public function setSES(EmailService $ses) { $this->ses = $ses; return $this; } /** * Set HTTP method * * @param string $verb * @return EmailServiceRequest $this */ public function setVerb($verb) { $this->verb = $verb; return $this; } /** * Set request parameter * * @param string $key Key * @param string $value Value * @param boolean $replace Whether to replace the key if it already exists (default true) * @return EmailServiceRequest $this */ public function setParameter($key, $value, $replace = true) { if(!$replace && isset($this->parameters[$key])) { $temp = (array)($this->parameters[$key]); $temp[] = $value; $this->parameters[$key] = $temp; } else { $this->parameters[$key] = $value; } return $this; } /** * Get the params for the request * * @return array $params */ public function getParametersEncoded() { $params = array(); foreach ($this->parameters as $var => $value) { if(is_array($value)) { foreach($value as $v) { $params[] = $var.'='.$this->__customUrlEncode($v); } } else { $params[] = $var.'='.$this->__customUrlEncode($value); } } sort($params, SORT_STRING); return $params; } /** * Clear the request parameters * @return EmailServiceRequest $this */ public function clearParameters() { $this->parameters = array(); return $this; } /** * Instantiate and setup CURL handler for sending requests. * Instance is cashed in `$this->curl_handler` * * @return resource $curl_handler */ protected function getCurlHandler() { if (!empty($this->curl_handler)) return $this->curl_handler; $curl = curl_init(); curl_setopt($curl, CURLOPT_USERAGENT, 'EmailService/php'); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, ($this->ses->verifyHost() ? 2 : 0)); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, ($this->ses->verifyPeer() ? 1 : 0)); curl_setopt($curl, CURLOPT_HEADER, false); curl_setopt($curl, CURLOPT_RETURNTRANSFER, false); curl_setopt($curl, CURLOPT_WRITEFUNCTION, array(&$this, '__responseWriteCallback')); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); foreach(self::$curlOptions as $option => $value) { curl_setopt($curl, $option, $value); } $this->curl_handler = $curl; return $this->curl_handler; } /** * Get the response * * @return object | false */ public function getResponse() { $url = 'https://'.$this->ses->getHost().'/'; $query = implode('&', $this->getParametersEncoded()); $headers = $this->getHeaders($query); $curl_handler = $this->getCurlHandler(); curl_setopt($curl_handler, CURLOPT_CUSTOMREQUEST, $this->verb); // Request types switch ($this->verb) { case 'GET': case 'DELETE': $url .= '?'.$query; break; case 'POST': curl_setopt($curl_handler, CURLOPT_POSTFIELDS, $query); $headers[] = 'Content-Type: application/x-www-form-urlencoded'; break; } curl_setopt($curl_handler, CURLOPT_HTTPHEADER, $headers); curl_setopt($curl_handler, CURLOPT_URL, $url); // Execute, grab errors if (curl_exec($curl_handler)) { $this->response->code = curl_getinfo($curl_handler, CURLINFO_HTTP_CODE); } else { $this->response->error = array( 'curl' => true, 'code' => curl_errno($curl_handler), 'message' => curl_error($curl_handler), ); } // cleanup for reusing the current instance for multiple requests curl_setopt($curl_handler, CURLOPT_POSTFIELDS, ''); $this->parameters = array(); // Parse body into XML if ($this->response->error === false && !empty($this->response->body)) { $this->response->body = simplexml_load_string($this->response->body); // Grab SES errors if (!in_array($this->response->code, array(200, 201, 202, 204)) && isset($this->response->body->Error)) { $error = $this->response->body->Error; $output = array(); $output['curl'] = false; $output['Error'] = array(); $output['Error']['Type'] = (string)$error->Type; $output['Error']['Code'] = (string)$error->Code; $output['Error']['Message'] = (string)$error->Message; $output['RequestId'] = (string)$this->response->body->RequestId; $this->response->error = $output; unset($this->response->body); } } $response = $this->response; $this->response = (object) array('body' => '', 'code' => 0, 'error' => false); return $response; } /** * Get request headers * @param string $query * @return array */ protected function getHeaders($query) { $headers = array(); if ($this->ses->getRequestSignatureVersion() == EmailService::REQUEST_SIGNATURE_V4) { $date = (new \DateTime('now', new \DateTimeZone('UTC')))->format('Ymd\THis\Z'); $headers[] = 'X-Amz-Date: ' . $date; $headers[] = 'Host: ' . $this->ses->getHost(); $headers[] = 'Authorization: ' . $this->__getAuthHeaderV4($date, $query); } else { // must be in format 'Sun, 06 Nov 1994 08:49:37 GMT' $date = gmdate('D, d M Y H:i:s e'); $auth = 'AWS3-HTTPS AWSAccessKeyId='.$this->ses->getAccessKey(); $auth .= ',Algorithm=HmacSHA256,Signature='.$this->__getSignature($date); $headers[] = 'Date: ' . $date; $headers[] = 'Host: ' . $this->ses->getHost(); $headers[] = 'X-Amzn-Authorization: ' . $auth; } return $headers; } /** * Destroy any leftover handlers */ public function __destruct() { if (!empty($this->curl_handler)) @curl_close($this->curl_handler); } /** * CURL write callback * * @param resource $curl CURL resource * @param string $data Data * @return integer */ private function __responseWriteCallback($curl, $data) { if (!isset($this->response->body)) { $this->response->body = $data; } else { $this->response->body .= $data; } return strlen($data); } /** * Contributed by afx114 * URL encode the parameters as per http://docs.amazonwebservices.com/AWSECommerceService/latest/DG/index.html?Query_QueryAuth.html * PHP's rawurlencode() follows RFC 1738, not RFC 3986 as required by Amazon. The only difference is the tilde (~), so convert it back after rawurlencode * See: http://www.morganney.com/blog/API/AWS-Product-Advertising-API-Requires-a-Signed-Request.php * * @param string $var String to encode * @return string */ private function __customUrlEncode($var) { return str_replace('%7E', '~', rawurlencode($var)); } /** * Generate the auth string using Hmac-SHA256 * * @internal Used by EmailServiceRequest::getResponse() * @param string $string String to sign * @return string */ private function __getSignature($string) { return base64_encode(hash_hmac('sha256', $string, $this->ses->getSecretKey(), true)); } /** * @param string $key * @param string $dateStamp * @param string $regionName * @param string $serviceName * @param string $algo * @return string */ private function __getSigningKey($key, $dateStamp, $regionName, $serviceName, $algo) { $kDate = hash_hmac($algo, $dateStamp, 'AWS4' . $key, true); $kRegion = hash_hmac($algo, $regionName, $kDate, true); $kService = hash_hmac($algo, $serviceName, $kRegion, true); return hash_hmac($algo,'aws4_request', $kService, true); } /** * Implementation of AWS Signature Version 4 * @see https://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html * @param string $amz_datetime * @param string $query * @return string */ private function __getAuthHeaderV4($amz_datetime, $query) { $amz_date = substr($amz_datetime, 0, 8); $algo = 'sha256'; $aws_algo = 'AWS4-HMAC-' . strtoupper($algo); $host_parts = explode('.', $this->ses->getHost()); $service = $host_parts[0]; $region = $host_parts[1]; $canonical_uri = '/'; if($this->verb === 'POST') { $canonical_querystring = ''; $payload_data = $query; } else { $canonical_querystring = $query; $payload_data = ''; } // ************* TASK 1: CREATE A CANONICAL REQUEST ************* $canonical_headers_list = [ 'host:' . $this->ses->getHost(), 'x-amz-date:' . $amz_datetime ]; $canonical_headers = implode("\n", $canonical_headers_list) . "\n"; $signed_headers = 'host;x-amz-date'; $payload_hash = hash($algo, $payload_data, false); $canonical_request = implode("\n", array( $this->verb, $canonical_uri, $canonical_querystring, $canonical_headers, $signed_headers, $payload_hash )); // ************* TASK 2: CREATE THE STRING TO SIGN************* $credential_scope = $amz_date. '/' . $region . '/' . $service . '/' . 'aws4_request'; $string_to_sign = implode("\n", array( $aws_algo, $amz_datetime, $credential_scope, hash($algo, $canonical_request, false) )); // ************* TASK 3: CALCULATE THE SIGNATURE ************* // Create the signing key using the function defined above. $signing_key = $this->__getSigningKey($this->ses->getSecretKey(), $amz_date, $region, $service, $algo); // Sign the string_to_sign using the signing_key $signature = hash_hmac($algo, $string_to_sign, $signing_key, false); // ************* TASK 4: ADD SIGNING INFORMATION TO THE REQUEST ************* return $aws_algo . ' ' . implode(', ', array( 'Credential=' . $this->ses->getAccessKey() . '/' . $credential_scope, 'SignedHeaders=' . $signed_headers , 'Signature=' . $signature )); } } amazonses/amazonses.php 0000644 00000011230 15173067213 0011257 0 ustar 00 <?php /** * Class GOSMTP_Mailer_AmazonSES. * * @since 1.0.0 */ namespace GOSMTP\Mailer\AmazonSES; use GOSMTP\Mailer\Loader; use GOSMTP\mailer\amazonses\EmailService; use GOSMTP\mailer\amazonses\EmailServiceMessage; class AmazonSES extends Loader{ var $title = 'AmazonSES'; var $mailer = 'amazonses'; var $client = null; public function send(){ global $phpmailer; if ($phpmailer->preSend()) { $response = $this->postSend(); return $this->handle_response( $response ); } return $this->handle_response(new \WP_Error(400, 'Unable to send mail for some reason!', [])); } public function postSend(){ global $phpmailer; $mime = chunk_split(base64_encode($phpmailer->getSentMIMEMessage()), 76, "\n"); $options = $this->getMailerOption(); $region = 'email.' . $options['region'] . '.amazonaws.com'; $ses = new EmailService($options['access_key'], $options['secret_key'], $region, false); $response = $ses->sendRawEmail($mime); if(is_wp_error($response)){ $return_response = new \WP_Error($response->get_error_code(), $response->get_error_message(), $response->get_error_messages()); }else{ $resp_body = wp_remote_retrieve_body($response); $resp_code = wp_remote_retrieve_response_code($response); $resp_body = \json_decode($resp_body, true); if(!empty($response['MessageId'])){ $msgId = $response['MessageId']; $status = __('Email sent successfully'); $return_response = [ 'status' => true, 'code' => 200, 'messageId' => $msgId, 'message' => $status ]; }else{ $err_code = $resp_code; $error_text = ['']; if( ! empty( $resp_body['error'] ) && is_array( $resp_body['error'] ) ){ $message = $resp_body['error']['message']; $error_text[] = $this->message_formatting( $message, $code ); }else{ $error_text[] = $this->get_response_error_message($response); } $error_msg = implode( '\r\n', array_map( 'esc_textarea', array_filter( $error_text ) ) ); $return_response = new \WP_Error($err_code, $error_msg, $resp_body); } } return $return_response; } public function email_checker($data){ $region= 'email.' . $data['amazonses']['region'] . '.amazonaws.com'; set_error_handler(function ($errno, $errstr, $errfile, $errline) { throw new \ErrorException($errstr, 0, $errno, $errfile, $errline); }); $ses = new EmailService($data['amazonses']['access_key'], $data['amazonses']['secret_key'], $region, false); try{ $ses->listVerifiedEmailAddresses(); }catch(\Exception $e) { return new \WP_Error(423, $e->getMessage()); } return false; } public function load_field(){ $fields = array( 'access_key' => array( 'title' => __('Access Key'), 'type' => 'password', ), 'secret_key' => array( 'title' => __('Secret Key'), 'type' => 'password', 'desc' => __( 'Follow this link to get a Secret Key from AmazonSES: <a href="https://aws.amazon.com/blogs/security/wheres-my-secret-access-key/" target="_blank">Secret Key.</a>' ), ), 'region' => array( 'title' => __('Region'), 'type' => 'select', 'list' => array( 'us-east-1' => __('US East (N. Virginia)', 'gosmtp'), 'us-east-2' => __('US East (Ohio)', 'gosmtp'), 'us-west-1' => __('US West (N. California)', 'gosmtp'), 'us-west-2' => __('US West (Oregon)', 'gosmtp'), 'ca-central-1' => __('Canada (Central)', 'gosmtp'), 'eu-west-1' => __('EU (Ireland)', 'gosmtp'), 'eu-west-2' => __('EU (London)', 'gosmtp'), 'eu-west-3' => __('Europe (Paris)', 'gosmtp'), 'eu-central-1' => __('EU (Frankfurt)', 'gosmtp'), 'eu-south-1' => __('Europe (Milan)', 'gosmtp'), 'eu-north-1' => __('Europe (Stockholm)', 'gosmtp'), 'ap-south-1' => __('Asia Pacific (Mumbai)', 'gosmtp'), 'ap-northeast-2' => __('Asia Pacific (Seoul)', 'gosmtp'), 'ap-southeast-1' => __('Asia Pacific (Singapore)', 'gosmtp'), 'ap-southeast-2' => __('Asia Pacific (Sydney)', 'gosmtp'), 'ap-northeast-1' => __('Asia Pacific (Tokyo)', 'gosmtp'), 'sa-east-1' => __('South America (Sao Paulo)', 'gosmtp'), 'me-south-1' => __('Middle East (Bahrain)', 'gosmtp'), 'us-gov-west-1' => __('AWS GovCloud (US)', 'gosmtp'), 'af-south-1' => __('Africa (Cape Town)', 'gosmtp'), 'cn-northwest-1' => __('China (Ningxia)', 'gosmtp') ), 'desc' => __( 'Define which endpoint you want to use for sending messages.<br>If you are operating under EU laws, you may be required to use EU region. <a href="https://aws.amazon.com/about-aws/global-infrastructure/regions_az/" target="_blank">More information</a> on aws.amazon.com.' ), ) ); return $fields; } } gmail/gmail.php 0000644 00000025746 15173067213 0007462 0 ustar 00 <?php /** * Class GOSMTP_Mailer_Gmail. * * @since 1.0.0 */ namespace GOSMTP\Mailer\Gmail; use GOSMTP\Mailer\Loader; class Gmail extends Loader{ var $title = 'Gmail'; var $mailer = 'gmail'; var $isOk = 200; var $url = 'https://gmail.googleapis.com/gmail/v1/users/me/messages/send'; public function getRedirectUrl($query = ''){ // TODO check and change this return admin_url().'admin.php?page=gosmtp'.$query; } public function send(){ global $phpmailer; if($phpmailer->preSend()){ $response = $this->postSend(); return $this->handle_response( $response ); } return $this->handle_response(new \WP_Error(400, 'Unable to send mail for some reason!', [])); } protected function postSend(){ global $phpmailer; try{ $access_token = $this->getAccessToken($this->getMailerOption()); if(is_wp_error($access_token)){ return $access_token->get_error_message(); } $mime = base64_encode($phpmailer->getSentMIMEMessage()); $body = array( "raw" =>$mime, ); $params = array( 'method' => 'POST', 'headers' => [ 'Authorization' => 'Bearer '. $access_token, 'Content-Type' => 'application/json', 'Accept' => 'application/json', ], 'body' => wp_json_encode($body) ); $response = wp_remote_request($this->url, $params); if(is_wp_error($response)){ $return_response = new \WP_Error($response->get_error_code(), $response->get_error_message(), $response->get_error_messages()); }else{ $resp_body = wp_remote_retrieve_body($response); $resp_code = wp_remote_retrieve_response_code($response); $resp_body = \json_decode($resp_body, true); if($this->isOk == $resp_code){ $msgId = isset( $resp_body['id'] ) ? $resp_body['id'] : ''; $status = 'Email sent successfully'; $return_response = [ 'status' => true, 'code' => $resp_code, 'messageId' => $msgId, 'message' => $status ]; }else{ $err_code = $resp_code; $error_text = ['']; if( ! empty( $resp_body['error'] ) && is_array( $resp_body['error'] ) ){ $message = $resp_body['error']['message']; $code = !empty( $resp_body['error']['code'] ) ? $resp_body['error']['code'] : ''; $error_text[] = $this->message_formatting( $message, $code ); }else{ $error_text[] = $this->get_response_error_message($response); } $error_msg = implode( '\r\n', array_map( 'esc_textarea', array_filter( $error_text ) ) ); $return_response = new \WP_Error($err_code, $error_msg, $resp_body); } } }catch(\Exception $e){ $return_Response = new \WP_Error(423, $e->getMessage(), []); } return $return_response; } // get access token private function getAccessToken($options){ $accessToken = $options['access_token']; // check if expired or will be expired in 300 seconds if( ($options['expire_stamp'] - 300) < time()){ $state = ($this->conn_id === 0 ? '' : '-'.$this->conn_id); $client_id = $this->getOption('client_id', $this->mailer); $client_secret = $this->getOption('client_secret', $this->mailer); $redirect_url = $this->getRedirectUrl('&auth=gmail'); $google_client = new \GOSMTP\mailer\gmail\Auth($client_id, $client_secret, $redirect_url, $state); $tokens = $google_client->sendTokenRequest('refresh_token', [ 'refresh_token' => $options['refresh_token'] ]); if(is_wp_error($tokens)) { return $tokens->get_error_message(); } $this->saveNewTokens($tokens); $accessToken = $tokens['access_token']; } return $accessToken; } //save new token when expire time exeed private function saveNewTokens($tokens){ $tokens['refresh_token'] = empty($tokens['refresh_token']) ? $this->getOption('refresh_token', $this->mailer) : $tokens['refresh_token']; if(empty($tokens['access_token']) || empty($tokens['refresh_token'])){ return false; } $this->update_option('access_token', $tokens['access_token'], $this->mailer); $this->update_option('refresh_token', $tokens['refresh_token'], $this->mailer); $this->update_option('expire_stamp', $tokens['expires_in'] + time(), $this->mailer); $this->update_option('expires_in', $tokens['expires_in'], $this->mailer); return true; } //generate access token and refresh token and update in data base. public function set_token(){ $errors = []; $clientId = $this->getOption('client_id', $this->mailer); $clientSecret = $this->getOption('client_secret', $this->mailer); $accessToken = $this->getOption('access_token', $this->mailer); $authToken = $this->getOption('auth_token', $this->mailer); if(!$accessToken && $authToken ){ $body = [ 'code' => $authToken, 'grant_type' => 'authorization_code', 'redirect_uri' => $this->getRedirectUrl('&auth=gmail'), 'client_id' => $clientId, 'client_secret' => $clientSecret ]; $tokens = $this->makeRequest('https://accounts.google.com/o/oauth2/token', $body, 'POST'); if(is_wp_error($tokens)){ return new \WP_Error(423, $tokens->get_error_message()); }else{ $this->update_option('access_token', $tokens['access_token'], $this->mailer); $this->update_option('refresh_token', $tokens['refresh_token'], $this->mailer); $this->update_option('auth_token', '', $this->mailer); $this->update_option('expire_stamp', time() + $tokens['expires_in'], $this->mailer); $this->update_option('expires_in', $tokens['expires_in'], $this->mailer); $this->update_option('version', 2, $this->mailer); } }elseif(!$authToken && !$accessToken){ return new \WP_Error(423, __('Please Provide Auth Token.', 'GOSMTP')); } return true; } private function makeRequest($url, $bodyArgs, $type = 'GET', $headers = false){ if(!$headers){ $headers = array( 'Content-Type' => 'application/http', 'Content-Transfer-Encoding' => 'binary', 'MIME-Version' => '1.0', ); } $args = array( 'headers' => $headers ); if($bodyArgs){ $args['body'] = json_encode($bodyArgs); } $args['method'] = $type; $request = wp_remote_request($url, $args); if(is_wp_error($request)){ $message = $request->get_error_message(); return new \WP_Error(423, $message); } $body = json_decode(wp_remote_retrieve_body($request), true); if(!empty($body['error'])){ $error = 'Unknown Error'; if(isset($body['error_description'])){ $error = $body['error_description']; }elseif(!empty($body['error']['message'])){ $error = $body['error']['message']; } return new \WP_Error(423, $error); } return $body; } public function get_auth_url() { $state = ($this->conn_id === 0 ? '' : '-'.$this->conn_id); $client_id = $this->getOption('client_id', $this->mailer); $client_secret = $this->getOption('client_secret', $this->mailer); $redirect_url = $this->getRedirectUrl('&auth=gmail'); $google_client = new \GOSMTP\mailer\gmail\Auth($client_id, $client_secret, $redirect_url, $state); if($google_client->getAuthUrl()){ return $google_client->getAuthUrl(); } } public function load_field(){ $this->gmail_init(); $access_token = $this->getOption('access_token', $this->mailer); $client_id = $this->getOption('client_id', $this->mailer); $client_secret = $this->getOption('client_secret', $this->mailer); $refresh_token = $this->getOption('refresh_token', $this->mailer); $mail_type = $this->getOption('mail_type', $this->mailer); $deactivate = !empty($refresh_token) && !empty($access_token) && $this->mailer == $mail_type; $activate = !empty($client_id) && !empty($client_secret) && empty($access_token) && empty($refresh_token); $readonly = $deactivate ? 'readonly' : ''; $fields = array( 'client_id' => array( 'title' => __('Client ID'), 'type' => 'text', 'desc' => '', 'attr'=> $readonly, ), 'client_secret' => array( 'title' => __('Client Secret'), 'type' => 'password', 'desc' => '', 'attr'=> $readonly, ), 'authorized_redirect_uri' => array( 'title' => __('Authorized redirect URI'), 'type' => 'copy', 'id' => 'gmail_redirect_uri', 'attr'=>'readonly', 'default' => $this->getRedirectUrl('&auth=gmail'), 'desc' => __('Please copy this URL into the "Authorized redirect URIs" field of your Google web application.') ), ); if($activate){ $fields['get_acces_token'] = array( 'title' => __('Get Access Token'), 'type' => 'button', 'class'=>'access_token', 'default' => 'Get Access Token', 'href' => $this->get_auth_url(), 'attr' => 'data-field=auth', ); }elseif($deactivate){ $fields['get_acces_token'] = array( 'title' => __('Deactivate Access Token'), 'type' => 'button', 'class'=>'deactivate_token', 'default' => 'Deactivate Access Token', 'href' => $this->getRedirectUrl().($this->conn_id !== 0 ? '&type=edit&conn_id='.$this->conn_id.'&act=deactivate_token#gosmtp-connections-settings' : '&act=deactivate_token'), 'attr' => 'data-field=auth', ); }else{ $fields['get_acces_token'] = array( 'title' => __('Get Access Token'), 'type' => 'notice', 'default' => __('You need to save settings with Client ID and Client Secret before you can proceed.'), ); } return $fields; } public function gmail_init(){ $options = $this->getMailerOption(); // Update auth URl when user succesfull regirect our page if( empty($options['access_token']) && empty($options['refresh_token']) && isset( $_GET['auth_code'] ) && isset( $_GET['auth'] ) && $this->mailer == $_GET['auth'] && strlen($this->conn_id) > 0 ){ if( !empty(gosmtp_optget('conn_id')) && $this->conn_id === 0 ){ return; } $auth_code = gosmtp_optget('auth_code'); $this->update_option('auth_token', $auth_code, $this->mailer); $resp = ''; if($this->set_token()){ $resp = __('Token Updated Sucessfully'); }elseif(is_wp_error($this->set_token())){ $resp = $this->set_token()->get_error_message(); }; $query = ''; if( !is_numeric($this->conn_id) ){ $query = '&type=edit&conn_id='.$this->conn_id.$query.'#gosmtp-connections-settings'; } echo '<script> alert("'.$resp.'"); var url = "'.$this->getRedirectUrl($query).'"; history.pushState({urlPath:url},"",url); </script>'; } // Delete all the tokens or expire stamp when user click deactivate access token if(isset($_GET['act']) && $_GET['act'] == 'deactivate_token'){ if(!empty(gosmtp_optget('conn_id')) && $this->conn_id === 0){ return; } $this->delete_option('refresh_token', $this->mailer); $this->delete_option('expire_stamp', $this->mailer); $this->delete_option('expires_in', $this->mailer); $this->delete_option('version', $this->mailer); $this->delete_option('access_token', $this->mailer); $query = ''; if(!is_numeric($this->conn_id)){ $query = '&type=edit&conn_id='.$this->conn_id.$query.'#gosmtp-connections-settings'; } if(isset($_GET['conn_id'])){ echo '<script> var url = "'.$this->getRedirectUrl($query).'"; history.pushState({urlPath:url},"",url); </script>'; } } } } gmail/auth.php 0000644 00000013040 15173067213 0007312 0 ustar 00 <?php namespace GOSMTP\mailer\gmail; class Auth{ private $client_id; private $client_secret; private $redirect_uri; private $state; private $options; private $accessTokenMethod = 'POST'; public function __construct($client_id = '', $client_secret = '', $redirect_uri = '', $state = ''){ $this->client_id = $client_id; $this->client_secret = $client_secret; $this->redirect_uri = $redirect_uri; $this->state = $state; $this->options = $this->getConfig(); } private function getConfig(){ return array( 'client_id' => $this->client_id, 'client_secret' => $this->client_secret, 'redirect_uri' => $this->redirect_uri, 'urlAuthorize' => 'https://accounts.google.com/o/oauth2/auth', 'urlAccessToken' => 'https://www.googleapis.com/oauth2/v4/token', 'urlResourceOwnerDetails' => '', 'scopes' => 'https://www.googleapis.com/auth/gmail.compose', 'access_type' => 'offline', 'include_granted_scopes' => 'true', 'approval_prompt' => 'force', 'state' => $this->state, ); } public function setClientId($client_id){ $this->client_id= $client_id; return true; } public function setClientSecret($client_secret){ $this->client_secret = $client_secret; return true; } public function add_scope($scope){ if(is_array($scope)){ $separator = ','; $this->options['scope'] = implode($separator, $scope); return true; } $this->options['scope'] = $scope; return true; } public function set_access_type($access_type){ $this->options['access_type'] = $access_type; return true; } public function set_approval_prompt($approval_prompt){ $this->options['approval_prompt'] = $approval_prompt; return true; } public function getAuthUrl(){ return $this->getAuthorizationUrl(); } public function getAuthorizationUrl($options = []){ $base = $this->options['urlAuthorize']; $params = $this->getAuthorizationParameters($options); $query = http_build_query($params, null, '&', \PHP_QUERY_RFC3986); return $this->appendQuery($base, $query); } private function getAuthorizationParameters($options){ if(empty($options['scope'])){ $options['scope'] = $this->options['scopes']; } $options += [ 'access_type' => $this->options['access_type'], 'include_granted_scopes' => $this->options['include_granted_scopes'], 'response_type' => 'code', 'state' => $this->getRandomState().$this->options['state'], 'approval_prompt' => $this->options['approval_prompt'], ]; if(is_array($options['scope'])){ $separator = ','; $options['scope'] = implode($separator, $options['scope']); } // Store the state as it may need to be accessed later on. $this->options['state'] = $options['state']; // Business code layer might set a different redirect_uri parameter // depending on the context, leave it as-is if(!isset($options['redirect_uri'])){ $options['redirect_uri'] = $this->options['redirect_uri']; } $options['client_id'] = $this->options['client_id']; return $options; } protected function getRandomState($length = 32){ // Converting bytes to hex will always double length. Hence, we can reduce // the amount of bytes by half to produce the correct length. $state = bin2hex(random_bytes($length / 2)); update_option('_gosmtp_last_generated_state', $state); return $state; } protected function appendQuery($url, $query){ $query = trim($query, '?&'); if($query){ $glue = strstr($url, '?') === false ? '?' : '&'; return $url . $glue . $query; } return $url; } public function sendTokenRequest($type, $params){ try { $tokens = $this->getAccessToken($type, $params); return $tokens; } catch (\Exception $exception) { return new \WP_Error(423, $exception->getMessage()); } } /** * Requests an access token using a specified grant and option set. * * @param mixed $grant * @param array $options * @throws \Exception * @return array tokens */ public function getAccessToken($grant, array $options = []){ $params = [ 'client_id' => $this->options['client_id'], 'client_secret' => $this->options['client_secret'], 'redirect_uri' => $this->options['redirect_uri'], 'grant_type' => $grant, ]; $params += $options; $requestData = $this->getAccessTokenRequestDetails($params); $response = wp_remote_request($requestData['url'], $requestData['params']); if(is_wp_error($response)) { throw new \Exception( $response->get_error_message() ); return $response; } $responseBody = wp_remote_retrieve_body($response); if(false === is_array($response)){ throw new \Exception( 'Invalid response received from Authorization Server. Expected JSON.' ); } if(empty(['access_token'])){ throw new \Exception( 'Invalid response received from Authorization Server.' ); } return \json_decode($responseBody, true); } /** * Returns a prepared request for requesting an access token. * * @param array $params Query string parameters * @return array $requestDetails */ protected function getAccessTokenRequestDetails($params){ $method = $this->accessTokenMethod; $url = $this->options['urlAccessToken']; $options = http_build_query($params, null, '&', \PHP_QUERY_RFC3986); return [ 'url' => $url, 'params' => [ 'method' => $method, 'body' => $options, 'headers' => [ 'content-type' => 'application/x-www-form-urlencoded' ] ] ]; } } zoho.php 0000644 00000037122 15173067213 0006246 0 ustar 00 <?php /** * TODO: need to cleen code and properer arrange * Class GOSMTP_Mailer_Zoho. * * @since 1.0.0 */ namespace GOSMTP\Mailer; use GOSMTP\Mailer\Loader; class Zoho extends Loader{ var $title = 'Zoho'; var $mailer = 'zoho'; var $scope = 'VirtualOffice.messages.CREATE,VirtualOffice.accounts.READ'; var $send_code = 200; var $api_url = ''; var $oauth_url = ''; var $body = []; var $lang = []; private $allowed_exts = array('xlsx', 'xls', 'ods', 'docx', 'docm', 'doc', 'csv', 'pdf', 'txt', 'gif', 'jpg', 'jpeg', 'png', 'tif', 'tiff', 'rtf', 'bmp', 'cgm', 'css', 'shtml', 'html', 'htm', 'zip', 'xml', 'ppt', 'pptx', 'tar', 'ez', 'ics', 'mobi', 'msg', 'pub', 'eps', 'odt', 'mp3', 'm4a', 'm4v', 'wma', 'ogg', 'flac', 'wav', 'aif', 'aifc', 'aiff', 'mp4', 'mov', 'avi', 'mkv', 'mpeg', 'mpg', 'wmv'); public function getLang($str = ''){ $this->lang = array( 'OK' => __('Mailer successfully configured!'), 'unauthorized_client' => __('OAuth Client is Invalid'), 'invalid_client' => __('Invalid Client ID (or) client Credentials did not match.'), 'invalid_code' => __('Code Expired (or) Invalid Refresh Token.'), 'invalid_redirect_uri' => __('Invalid Redirect Url configured'), 'invalid_client_secret' => __('Client Secret did not match.'), 'INVALID_TICKET' => __('Invalid Client Secret'), 'INVALID_OAUTHTOKEN' => __('Authtoken invalidated'), 'access_denied' => __('Multiple requests failed with same Refresh Token.'), 'general_error' => __('Something went wrong'), 'remote_token_error' => __('Error when getting the remote token.'), 'no_user' => __('No User present.'), 'token_limit_reached' => __('Refresh token limit reached.'), 'refresh_token_limit_reached' => __('The limit for refresh token reached.'), 'access_token_limit_reached' => __('The limit for access token reached.'), 'invalid_client_type' => __('Invalid client type'), 'invalid_authtoken' => __('Authtoken invalidated'), 'invalid_operation_type' => __('The scope has an invalid operation.'), 'URL_RULE_NOT_CONFIGURED' => __('Please configure zoho api.'), 'invalid_from' => __('Your zoho account does not match with the from mail.'), ); if(!isset($this->lang[$str])){ return $str; } return $this->lang[$str]; } public function getRedirectUrl($query = ''){ // TODO check and change this return admin_url().'admin.php?page=gosmtp'.$query; } public function send(){ global $phpmailer; $phpmailer->isMail(); $this->setConfig(); if($phpmailer->preSend()){ return $this->handle_response( $this->postSend() ); } return $this->handle_response(new \WP_Error(400, 'Unable to send mail for some reason!', [])); } public function setConfig(){ $domain_name = $this->getOption('domain_name', $this->mailer, 'com'); $this->api_url = 'https://mail.zoho.'.$domain_name.'/api/accounts'; $this->oauth_url = 'https://accounts.zoho.'.$domain_name.'/oauth/v2/'; } public function postSend(){ global $phpmailer; $options = $this->getMailerOption(); $options['access_token'] = $this->getAccessToken($options); $this->body['fromAddress'] = $phpmailer->FromName.'<'.$phpmailer->From.'>'; $this->body['subject'] = $phpmailer->Subject; $this->set_content($phpmailer->Body); $this->set_recipients( array( 'toAddress' => $phpmailer->getToAddresses(), 'ccAddress' => $phpmailer->getCcAddresses(), 'bccAddress' => $phpmailer->getBccAddresses(), 'replyTo' => $phpmailer->getReplyToAddresses() ) ); $attachments = $phpmailer->getAttachments(); if(!empty($attachments)){ $this->set_attachments($attachments); } $headers = [ 'Authorization' => 'Zoho-oauthtoken '.$options['access_token'], 'Content-Type' => 'application/json' ]; $params = array( 'headers' => $headers, 'body' => wp_json_encode($this->body) ); $accId = !empty($options['account_id']) ? $options['account_id'] : ''; $url = $this->api_url.'/'.$accId.'/messages'; // print_r(json_encode($this->body, JSON_PRETTY_PRINT)); $response = wp_safe_remote_post($url, $params); if(is_wp_error($response)){ $return_response = new \WP_Error($response->get_error_code(), $response->get_error_message(), $response->get_error_messages()); }else{ $resp_body = wp_remote_retrieve_body($response); $resp_code = wp_remote_retrieve_response_code($response); $isOk = $resp_code == $this->send_code; $resp_body = \json_decode($resp_body, true); if($isOk) { $msgId = isset( $resp_body['data']['messageId'] ) ? $resp_body['data']['messageId'] : ''; $status = isset($resp_body['status']['description']) ? $resp_body['status']['description'] : ''; $return_response = [ 'status' => true, 'code' => $resp_code, 'messageId' => $msgId, 'message' => $status ]; }else{ $msg = ($resp_code == 500 ) ? $resp_body['data']['moreInfo'] : $this->getLang($resp_body['data']['errorCode']); $return_response = new \WP_Error($resp_code, $msg , $resp_body); } } return $return_response; } public function set_content( $content ){ global $phpmailer; if( empty( $content ) ){ return; } if( is_array( $content ) ){ if( ! empty( $content['text'] ) ){ $this->body['mailFormat'] = 'plaintext'; } if( ! empty( $content['html'] ) ){ $this->body['mailFormat'] = 'html'; } $this->body['content'] = $content['text']; }else{ if( $phpmailer->ContentType === 'text/plain' ){ $this->body['mailFormat'] = 'plaintext'; }else{ $this->body['mailFormat'] = 'html'; } } $this->body['content'] = $content; } public function set_recipients( $recipients ) { global $phpmailer; if( empty( $recipients ) ){ return; } foreach( $recipients as $type => $emails ){ $tmp = ''; foreach( $emails as $key => $email ){ $tmp .= $type == 'replyTo' ? '<'.$email[0].'>' : ( empty($email[1]) ? $email[0] : $email[1].'<'.$email[0].'>' ); if( ( count($emails) - 1 ) != $key ){ $tmp .= ','; } } if(empty($tmp)){ continue; } $this->body[$type] = $tmp; } } public function set_attachments( $attachments = []){ $attachment_data = []; $count = 0; $ext = ''; foreach($attachments as $attachment){ if(!is_file($attachment[0]) || !is_readable($attachment[0])){ continue; } if(!empty($attachment[4])){ $ext = explode("/",$attachment[4])[1]; } $header = array( 'Authorization' => 'Zoho-oauthtoken '. $this->getOption('access_token', $this->mailer), 'Content-Type' => 'application/octet-stream' ); if(in_array($ext, $this->allowed_exts, true)){ $file_name = $attachment[2]; $content = file_get_contents($attachment[0]); $options = $this->getMailerOption(); $url = $this->api_url.'/'.$options['account_id'].'/messages/attachments'.'?fileName='.$file_name; $args = array( 'body' => $content, 'headers' => $header, 'method' => 'POST' ); $response = wp_remote_post($url, $args); $response_body = wp_remote_retrieve_body($response); $http_code = wp_remote_retrieve_response_code($response); $response_ = json_decode($response_body, true); if( isset($response_['data']['errorCode']) ){ $error = $response_['data']['errorCode']; } $attachments_ = array(); if($http_code == '200') { $attachments_['storeName'] = $response_['data']['storeName']; $attachments_['attachmentPath'] = $response_['data']['attachmentPath']; $attachments_['attachmentName'] = $response_['data']['attachmentName']; $attachment_data[$count] = $attachments_; $count = $count + 1; } } } if( count($attachment_data) > 0 ){ $this->body['attachments'] = $attachment_data; } } private function is_authorized(){ $options = $this->getMailerOption(); if(empty($options['refresh_token']) || empty($options['access_token']) || empty($options['account_id'])){ return false; } return true; } public function authentication_process(){ global $phpmailer; $options = $this->getMailerOption(); $response = $this->generate_tokens($options); if( !isset($response['access_token']) || !isset($response['refresh_token']) ){ return $response; } $access_token = $response['access_token']; $refresh_token = $response['refresh_token']; if( empty($options['account_id']) ){ $response = $this->zoho_account_id($access_token); if(!$response != true){ return $response; } } $this->delete_option('auth_code', $this->mailer); return 'OK'; } private function get_authcode_link($options){ $state = wp_create_nonce('redirect_url').($this->conn_id === 0 ? '' : '-'.$this->conn_id); $auth_url = $this->oauth_url ."auth?response_type=code&client_id=". $options['client_id'] ."&scope=". $this->scope ."&redirect_uri=".urlencode($this->getRedirectUrl('&auth=zoho'))."&prompt=consent&access_type=offline&state=". $state; return $auth_url; } public function generate_tokens($options){ $state = wp_create_nonce('redirect_url').($this->conn_id === 0 ? '' : '-'.$this->conn_id); $url = $this->oauth_url ."token?code=". $options['auth_code'] ."&client_id=". $options['client_id'] ."&client_secret=". $options['client_secret'] ."&redirect_uri=".urlencode($this->getRedirectUrl('&auth=zoho'))."&scope=".$this->scope."&grant_type=authorization_code&state=".$state; $response = wp_remote_retrieve_body(wp_remote_post( $url)); $response = json_decode($response, true); if(isset($response['error'])){ if($response['error'] == 'invalid_code'){ $this->delete_option('auth_code', $this->mailer); } return $response['error']; } $access_token = $response['access_token']; $refresh_token = $response['refresh_token']; $this->update_option('access_token', $access_token , $this->mailer); $this->update_option('refresh_token', $refresh_token, $this->mailer); return array( 'access_token' => $access_token, 'refresh_token' => $refresh_token ); } public function zoho_account_id($access_token = ''){ $from_email = $this->conn_id === 0 ? $this->getOption('from_email') : $this->getOption('from_email', $this->mailer,''); $accId = $this->getOption('account_id', $this->mailer, ''); if(!empty($accId)){ return; } $args = [ 'headers' => [ 'Authorization' => 'Zoho-oauthtoken '.$access_token ] ]; $response = wp_remote_retrieve_body(wp_remote_get( $this->api_url, $args)); $response = json_decode($response, true); if(empty($response)){ return 'general_error'; } if( isset($response['data']['errorCode']) ){ return $response['data']['errorCode']; } for($i=0; $i<count($response['data']); $i++){ for($j=0; $j<count($response['data'][$i]['sendMailDetails']); $j++) { if(strcmp($response['data'][$i]['sendMailDetails'][$j]['fromAddress'], $from_email) == 0){ $this->update_option('account_id', $response['data'][0]['accountId'], $this->mailer); }else{ return 'invalid_from'; } } } } public function getAccessToken( $options ){ $setup_time = $options['setup_timestamp']; $access_token = $options['access_token']; if(empty($setup_time) || time() - $setup_time > 3000){ $this->update_option('setup_timestamp', time(), $this->mailer); $url = $this->oauth_url.'token?refresh_token='.$options['refresh_token'].'&grant_type=refresh_token&client_id='.$options['client_id'].'&client_secret='.$options['client_secret'].'&redirect_uri='.urlencode($this->getRedirectUrl('&auth=zoho')).'&scope='.$this->scope; $response = wp_remote_retrieve_body( wp_remote_post( $url ) ); $response = json_decode($response); $access_token = $response->access_token; $this->update_option('access_token', $access_token, $this->mailer); } return $access_token; } public function load_field(){ $fields = array(); $options = $this->getMailerOption(); $client_id = $this->getOption('client_id', $this->mailer); $client_secret = $this->getOption('client_secret', $this->mailer); $opt_text = __('You need to save settings with Client ID and Client Secret before you can proceed.'); $opt_type = 'notice'; $opt_url = ''; $readonly = ''; $this->zoho_init(); $_button = ''; if(!empty($client_id) && !empty($client_secret) ){ $opt_type = $_button = 'button'; if(!$this->is_authorized()){ $opt_url = $this->get_authcode_link($options); $opt_text = __('Authorize Zoho Account'); }else{ $query = '&zoho-deactivate=1'; if(!is_numeric($this->conn_id)){ $query = '&type=edit&conn_id='.$this->conn_id.$query.'#gosmtp-connections-settings'; } $readonly = 'readonly=""'; $opt_url = $this->getRedirectUrl($query); $opt_text = 'Deactivate Access Token'; } } $fields = array( 'domain_name' => array( 'title' => __('Select domain name'), 'type' => 'select', 'list' => array( 'com' => '.com', 'eu' => '.eu', 'in' => '.in', 'com.cn' => '.com.cn', 'com.au' => '.com.au', 'jp' => '.jp', ), 'desc' => __( 'The name of the region the account is configured' ), ), 'client_id' => array( 'title' => __('Client Id'), 'type' => 'text', 'class'=>'zoho_client_id', 'desc' => __( 'Created in the developer console' ), 'attr' => $readonly ), 'client_secret' => array( 'title' => __('Client Secret'), 'type' => 'password', 'class'=>'zoho_client_secret', 'desc' => __( 'Created in the developer console' ), 'attr' => $readonly ), 'redirect_uri' => array( 'title' => __('Authorization Redirect URI'), 'type' => 'copy', 'id' => 'zoho_redirect_uri', 'attr' =>'readonly=""', 'default' => $this->getRedirectUrl('&auth=zoho'), 'desc' => __( 'Copy this URL into Redirect URI field of your Client Id creation' ), ), 'authorize' => array( 'title' => __('Authorize'), 'type' => $opt_type, 'default' => $opt_text, 'href' => $opt_url, 'class' => 'auth_class gosmtp-auto-width '.$_button, 'attr' => 'data-field=auth' ) ); return $fields; } public function zoho_deregister(){ if(!empty(gosmtp_optget('conn_id')) && $this->conn_id === 0){ return; } $this->delete_option('access_token', $this->mailer); $this->delete_option('refresh_token', $this->mailer); $this->delete_option('auth_code', $this->mailer); $this->delete_option('account_id', $this->mailer); $this->delete_option('setup_timestamp', $this->mailer); $query = ''; if(!is_numeric($this->conn_id)){ $query = '&type=edit&conn_id='.$this->conn_id.$query.'#gosmtp-connections-settings'; } if(isset($_GET['conn_id'])){ echo '<script> var url = "'.$this->getRedirectUrl($query).'"; history.pushState({urlPath:url},"",url); </script>'; } } public function zoho_init(){ $this->setConfig(); if(isset( $_GET['zoho-deactivate'] )){ $this->zoho_deregister(); return; } if( !$this->is_authorized() && isset( $_GET['auth_code'] ) && isset( $_GET['auth'] ) && $this->mailer == $_GET['auth'] && strlen($this->conn_id) > 0){ if( !empty(gosmtp_optget('conn_id')) && $this->conn_id === 0 ){ return; } // TODO sanitize $_GET['code'] $this->update_option('auth_code', gosmtp_optget('auth_code'), $this->mailer); $response = $this->authentication_process(); // var_dump($response); if( $response ){ $msg = is_array($this->getLang($response)) ? $this->getLang('general_error') : $this->getLang($response); } $query = ''; if(!is_numeric($this->conn_id)){ $query = '&type=edit&conn_id='.$this->conn_id.$query.'#gosmtp-connections-settings'; } echo '<script> alert("'.$msg.'") var url = "'.$this->getRedirectUrl($query).'"; history.pushState({urlPath:url},"",url); </script>'; } } }
| ver. 1.4 |
Github
|
.
| PHP 8.3.30 | Generation time: 0.8 |
proxy
|
phpinfo
|
Settings