HEX
Server: Apache
System: Linux 162-240-236-42.bluehost.com 3.10.0-1160.114.2.el7.x86_64 #1 SMP Wed Mar 20 15:54:52 UTC 2024 x86_64
User: bt667 (1004)
PHP: 8.2.29
Disabled: NONE
Upload Files
File: /home/bt667/www/wp-content/plugins/gmail-smtp/class.phpmaileroauthgoogle.php
<?php
/*
define ( 'SCOPES', implode ( ' ', array (
        \Google_Service_Gmail::GMAIL_COMPOSE 
) ) );
*/
class GmailXOAuth2 {

    private $oauthUserEmail = '';
    private $oauthRefreshToken = '';
    private $oauthClientId = '';
    private $oauthClientSecret = '';

    public function __construct(
        $UserEmail,
        $ClientSecret,
        $ClientId,
        $RefreshToken
    ) {
        $this->oauthClientId = $ClientId;
        $this->oauthClientSecret = $ClientSecret;
        $this->oauthRefreshToken = $RefreshToken;
        $this->oauthUserEmail = $UserEmail;
    }

        /*
         * @returns $google_client object
         */
    public static function getClient() {

        $google_client = new \Google_Client ();
        $options = gmail_smtp_get_option();
        $clientId = $options['oauth_client_id'];
        $clientSecret = $options['oauth_client_secret'];
        //$google_client->setApplicationName ( APPLICATION_NAME );
        $google_client->setScopes ( 'https://mail.google.com/' );
        $google_client->setClientId($clientId);
        $google_client->setClientSecret($clientSecret);
        $redirect_url = admin_url("options-general.php?page=gmail-smtp-settings&action=oauth_grant");
        $google_client->setRedirectUri($redirect_url);
        //$google_client->setAuthConfigFile ( APP_CREDENTIALS );
        /* Its a must to request for 'offile access type' */
        $google_client->setAccessType ( 'offline' );
        /*
        This forces the approval prompt for other sites when one site has already been given permission under the same project.
        Without this the approval prompt does not appear and no refresh token is returned.
        */
        $google_client->setApprovalPrompt ( 'force' );
        return $google_client;

    }

        /*
         * checks the credentials for the access token, if present; it returns that
         * or refreshes it if expired. 
         * if the credentials file is empty, it will return the authorization url to which you must redirect too 
         * for user user authorization 
         */
    public static function authenticate () {

        $client = GmailXOAuth2::getClient();
        $options = gmail_smtp_get_option();
        if (!empty($options['oauth_access_token'])) {

            $accessToken = $options['oauth_access_token'];

        } else {

            return array( 'authorization_uri' => $client->createAuthUrl() );

        }

        $client->setAccessToken($accessToken);

        // Refresh the token if it's expired.
        if ($client->isAccessTokenExpired()) {

            $client->refreshToken($client->getRefreshToken());

            $new_accessToken = $client->getAccessToken();

            $options['oauth_access_token'] = json_encode($new_accessToken); //json_encode the token since getAccessToken() no longer encodes it
            
            gmail_smtp_update_option($options);
            
            return json_decode($new_accessToken, true);

        }

        return json_decode($accessToken, true);

    }

        /*
         * call this in your callback (redirect url), code the authorization for and exchanges it for an 
         * access token. 
         * it stores this in the token file for future reference.
         * if the user denies your app access, it will still return just that error and not write to the token file
         */
    public static function resetCredentials( $authCode ) {

        $client = GmailXOAuth2::getClient();

        $accessToken = $client->authenticate( $authCode );
        
        $options = gmail_smtp_get_option();
        
        if(!empty($accessToken)) {
            if(isset($accessToken['error']) || isset($accessToken['error_description'])){
                echo '<div id="message" class="error"><p><strong>';
                esc_html_e('Error: '.$accessToken['error'].', Error Description: '.$accessToken['error_description'], 'gmail-smtp');
                echo '</strong></p></div>';
                return false;
            }
            //json_encode the token since authenticate() function returns it as an array now. It used to call getAccessToken() before which would return in json_encoded format.
            $options['oauth_access_token'] = json_encode($accessToken); 
            gmail_smtp_update_option($options);
            return $accessToken;

        }

        return false;

    }

    /**
     * GetOauth64
     * 
     * encode the user email related to this request along with the token in base64
     * this is used for authentication, in the phpmailer smtp class
     * 
     * @return string
     */
    public function getOauth64 () {

        $client = GmailXOAuth2::getClient();
        $options = gmail_smtp_get_option();
        
        if (!empty($options['oauth_access_token'])) {

            $accessToken = $options['oauth_access_token'];

        } else {

            return false;

        }

        $client->setAccessToken($accessToken);

        // Refresh the token if it's expired.
        if ($client->isAccessTokenExpired()) {

            $client->refreshToken($client->getRefreshToken());

            $accessToken = $client->getAccessToken();

            $options['oauth_access_token'] = json_encode($accessToken); //json_encode the token since getAccessToken() no longer encodes it
            gmail_smtp_update_option($options);

        }

        $offlineToken = GmailXOAuth2::request_offline_token();

        return base64_encode("user=" . $this->oauthUserEmail . "\001auth=Bearer " . $offlineToken . "\001\001");

    }

        /*
         * this makes a request to the Google API, using Curl to get another access token that we can use 
         * for authentication on the Gmail API when sending messages
         */
    private function request_offline_token() {

        $token_uri = "https://accounts.google.com/o/oauth2/token";
        $parameters = array(
                "grant_type" => 'refresh_token',
                "client_id" => $this->oauthClientId,
                "client_secret" => $this->oauthClientSecret,
                "refresh_token" => $this->oauthRefreshToken
        );

        $curl = curl_init($token_uri);

        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $parameters);
        curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

        $response = curl_exec($curl);
        curl_close($curl);

        $response = json_decode($response, true);

        return $response['access_token'];
    }

}