Plugin Directory

Changeset 3272615


Ignore:
Timestamp:
04/14/2025 03:43:49 PM (10 months ago)
Author:
bobintercom
Message:

Deploy version 3.0.0

Location:
intercom
Files:
66 added
20 edited
1 copied

Legend:

Unmodified
Added
Removed
  • intercom/tags/3.0.0/bootstrap.php

    r3036274 r3272615  
    66Author: Intercom
    77Author URI: https://www.intercom.io
    8 Version: 2.6.6
     8Version: 3.0.0
    99 */
    1010
    11 class IdentityVerificationCalculator
     11require_once __DIR__ . '/vendor/autoload.php';
     12use Firebase\JWT\JWT;
     13
     14class TimeProvider
     15{
     16    private static $mockTime = null;
     17
     18    public static function setMockTime($timestamp)
     19    {
     20        self::$mockTime = $timestamp;
     21    }
     22
     23    public static function resetMockTime()
     24    {
     25        self::$mockTime = null;
     26    }
     27
     28    public static function getCurrentTime()
     29    {
     30        return self::$mockTime !== null ? self::$mockTime : time();
     31    }
     32}
     33
     34class MessengerSecurityCalculator
    1235{
    1336  private $raw_data = array();
     
    2043  }
    2144
    22   public function identityVerificationComponent()
     45  public function messengerSecurityComponent()
    2346  {
    2447    $secret_key = $this->getSecretKey();
     48
    2549    if (empty($secret_key))
    2650    {
    27       return $this->emptyIdentityVerificationHashComponent();
    28     }
    29     if (array_key_exists("user_id", $this->getRawData()))
    30     {
    31       return $this->identityVerificationHashComponent("user_id");
    32     }
    33     if (array_key_exists("email", $this->getRawData()))
    34     {
    35       return $this->identityVerificationHashComponent("email");
    36     }
    37     return $this->emptyIdentityVerificationHashComponent();
    38   }
    39 
    40   private function emptyIdentityVerificationHashComponent()
    41   {
    42     return array();
    43   }
    44 
    45   private function identityVerificationHashComponent($key)
     51      return $this->getRawData();
     52    }
     53    if (array_key_exists("user_id", $this->getRawData()) || array_key_exists("email", $this->getRawData()))
     54    {
     55      return $this->messengerSecurityJWTComponent();
     56    }
     57
     58    return $this->getRawData();
     59  }
     60
     61  private function messengerSecurityJWTComponent()
    4662  {
    4763    $raw_data = $this->getRawData();
    48     return array("user_hash" => hash_hmac("sha256", $raw_data[$key], $this->getSecretKey()));
     64
     65    $filtered_data = $raw_data;
     66    $payload = array();
     67
     68    if (array_key_exists("email", $filtered_data)) {
     69      unset($filtered_data["email"]);
     70      $payload["user_id"] = $raw_data["email"];
     71      $payload["email"] = $raw_data["email"];
     72    }
     73    if (array_key_exists("user_id", $filtered_data)) {
     74      unset($filtered_data["user_id"]);
     75      $payload["user_id"] = $raw_data["user_id"];
     76    }
     77    if (array_key_exists("name", $filtered_data)) {
     78      unset($filtered_data["name"]);
     79      $payload["name"] = $raw_data["name"];
     80    }
     81
     82    $payload = array_merge($payload, apply_filters("intercom_sensitive_attributes", array()));
     83    $payload["exp"] = TimeProvider::getCurrentTime() + 3600;
     84
     85    $filtered_data["intercom_user_jwt"] = JWT::encode(
     86      $payload, $this->getSecretKey(),
     87      'HS256'
     88    );
     89
     90    return $filtered_data;
    4991  }
    5092
     
    5395    return $this->secret_key;
    5496  }
     97
    5598  private function getRawData()
    5699  {
     
    195238                    </p>
    196239                    <br/>
    197                     <div style="font-size:0.8em">If the Intercom application associated with your Wordpress is incorrect, please <a class="c__blue" href="$auth_url">click here</a> to reconnect with Intercom, to choose a new application.</div>
     240                    <div style="font-size:0.8em">If the Intercom application associated with your WordPress is incorrect, please <a class="c__blue" href="$auth_url">click here</a> to reconnect with Intercom, to choose a new application.</div>
    198241                  </div>
    199242                </div>
     
    358401  {
    359402    $user = new IntercomUser($this->wordpress_user, $this->raw_data);
    360     $settings = apply_filters("intercom_settings", $user->buildSettings());
    361     $identityVerificationCalculator = new IdentityVerificationCalculator($settings, $this->secret);
    362     $result = array_merge($settings, $identityVerificationCalculator->identityVerificationComponent());
    363     $result = $this->mergeConstants($result);
     403    $messengerSecurityCalculator = new MessengerSecurityCalculator($user->buildSettings(), $this->secret);
     404    $settings = $messengerSecurityCalculator->messengerSecurityComponent();
     405    $result = $this->mergeConstants(apply_filters("intercom_settings", $settings));
    364406    $result['installation_type'] = 'wordpress';
    365407    return $result;
     
    386428
    387429if (getenv('INTERCOM_PLUGIN_TEST') == '1' && !function_exists('apply_filters')) {
    388   function apply_filters($_, $value) {
     430  function apply_filters($key, $value) {
     431    if ($key == "intercom_sensitive_attributes") {
     432      $extra_data_key = 'INTERCOM_PLUGIN_TEST_JWT_DATA';
     433    } elseif ($key == "intercom_settings") {
     434      $extra_data_key = 'INTERCOM_PLUGIN_TEST_SETTINGS';
     435    }
     436
     437    $extra_data = getenv($extra_data_key);
     438    if ($extra_data) {
     439      $extra_data = json_decode($extra_data, true);
     440      return array_merge($value, $extra_data);
     441    }
     442
    389443    return $value;
    390444  }
     
    436490    {
    437491      $this->settings["email"] = WordPressEscaper::escJS($this->wordpress_user->user_email);
     492    }
     493    if (!empty($this->wordpress_user->ID))
     494    {
     495      $this->settings["user_id"] = WordPressEscaper::escJS($this->wordpress_user->ID);
    438496    }
    439497    if (!empty($this->wordpress_user->display_name))
  • intercom/tags/3.0.0/readme.md

    r1759316 r3272615  
    55# Compatibility
    66
    7 Requires PHP 5.6 or higher.
     7Requires PHP 7.2 or higher.
    88
    99# Local Testing
     
    1414INTERCOM_PLUGIN_TEST=1 phpunit
    1515```
    16 
    17 # Test the new version of the plugin with Intercom's Wordpress signup flow
    18 
    19 It is mandatory that you fully test the [intercom wordpress setup guide](https://app.intercom.io/a/start/wordpress) before you release a new update of the plugin.
    2016
    2117# Usage
     
    3127NB: This plugin injects a Javascript snippet on your website frontend containing dynamic user data. Some caching solutions will cache entire pages and should not be used with this plugin. Doing so may cause conversations to be delivered to the wrong user.
    3228
    33 # Pass extra parameters to the Intercom Messenger
     29# Pass custom data attributes to the Intercom Messenger
    3430
    35 Using the [Wordpress Hooks API](https://codex.wordpress.org/Plugin_API) `add_filter` method in your Wordpress theme you can pass extra parameters to the Intercom Messenger (see example below):
     31Using the [add_filter](https://developer.wordpress.org/reference/functions/add_filter) method in your WordPress theme or custom plugin you can pass [custom data attributes](https://www.intercom.com/help/en/articles/179-create-and-track-custom-data-attributes-cdas) to the Intercom Messenger (see example below):
    3632
    3733```php
    38 add_filter( 'intercom_settings', function( $settings ) {                                                 
    39   $settings['user_id'] = $user_id;               
    40   return $settings;                                                     
     34add_filter( 'intercom_settings', function( $settings ) {
     35  $settings['customer_type'] = $customer_type;
     36  return $settings;
    4137} );
    4238```
     
    4541# Users
    4642
    47 If a `$current_user` is present, we use their email as an identifier in the widget.
     43If a `$current_user` is present, we use their email and ID as an identifier in the widget.
    4844We recommend enabling [Identity Verification](https://docs.intercom.com/configure-intercom-for-your-product-or-site/staying-secure/enable-identity-verification-on-your-web-product) in the settings page.
    4945
  • intercom/tags/3.0.0/readme.txt

    r3036264 r3272615  
    1 === Plugin Name ===
    2 Contributors: bobintercom
     1=== Intercom ===
     2Contributors: bobintercom, jacopointercom
     3Tags: intercom, ai, customer, chat
     4Requires at least: 4.7.0
     5Tested up to: 6.7.2
     6Requires PHP: 7.2
    37License: Apache 2.0
    4 Tags: intercom, customer, chat
    5 Requires at least: 4.2.0
    6 Tested up to: 6.4.3
     8Stable tag: 3.0
    79
    8 The official WordPress plugin, built by Intercom.
    9 
    10 Chat with visitors to your website in real-time, capture them as leads, and convert them to customers.
     10Official Intercom WordPress plugin: Engage visitors in real time, power growth with AI, and convert leads into loyal customers.
    1111
    1212== Description ==
    1313
    14 [Intercom](https://www.intercom.io/) is a fundamentally new way for internet businesses to communicate with customers, personally, at scale. It's a customer communication platform with a suite of integrated products for every team – including sales, marketing, product, and support. Our products enable targeted communication with customers on your website, inside your web and mobile apps, and by email.
     14[Intercom](https://www.intercom.com/) is a next-generation customer communications platform that combines powerful live chat, proactive messaging, and advanced AI solutions — like our Fin AI chatbot — to help businesses instantly connect with customers.
    1515
    16 With this plugin, you can add the Intercom Messenger to your website in just a few clicks and start chatting to customers and visitors to your website right away.
    17 
    18 Your logged-in customers will be tracked in Intercom as users, and visitors who aren’t customers (or aren’t logged in) will be tracked as leads.
     16By installing the Intercom WordPress plugin, you can seamlessly add the Messenger to your site, track both logged-in users and visitors, and engage them right away. With Intercom’s industry-leading AI at your fingertips, you’ll deliver fast, personalized support and drive growth more effectively than ever before.
    1917
    2018== Installation ==
     
    2220Installing Intercom on your WordPress site takes just a few minutes.
    2321
    24 You can find full instructions on signing up and installing Intercom using the WordPress plugin [here](https://docs.intercom.io/install-on-your-product-or-site/other-ways-to-get-started/install-intercom-on-your-wordpress-site).
     22You can find full instructions on signing up and installing Intercom using the WordPress plugin [here](https://www.intercom.com/help/en/articles/173-install-intercom-on-your-wordpress-site).
    2523
    26 If you’re already an Intercom customer, you can also find instructions in the in-app [setup guide](https://app.intercom.com/a/apps/_/platform/guide) or [app store](https://app.intercom.com/a/apps/_/appstore?app_package_code=wordpress&search=wordpress). The first thing you’ll need to do is install and activate the plugin - you must be using WordPress v4.2.0 or higher and have the ability to install plugins in order to use this method.
     24If you’re already an Intercom customer, you can also find instructions in the in-app [setup guide](https://app.intercom.com/a/apps/_/platform/guide) or [app store](https://app.intercom.com/a/apps/_/appstore?app_package_code=wordpress&search=wordpress).
     25
     26The first thing you’ll need to do is install and activate the plugin - you must be using WordPress v4.9.0 or higher and have the ability to install plugins in order to use this method.
    2727
    2828Note: This plugin injects a Javascript snippet on your website frontend containing dynamic user data. Some caching solutions will cache entire pages and should not be used with this plugin. Doing so may cause conversations to be delivered to the wrong user.
     29
     30== Screenshots ==
     311. Plugin settings authenticate with Intercom settings_not_auth.png
     322. Plugin settings successfully authenticated with Intercom settings_auth.png
     333. Intercom widget used by customers to communicate with the business widget.png
     34== Changelog ==
     35
     36= 3.0 =
     37* Replaced user_hash with intercom_user_jwt https://www.intercom.com/help/en/articles/10589769-authenticating-users-in-the-messenger-with-json-web-tokens-jwts.
     38* Updated readme to follow guidelines.
     39* Added missing tests.
     40
     41== Upgrade Notice ==
     42
     43= 3.0 =
     44Upgrade the security of your messenger with the introduction of JWT - https://www.intercom.com/help/en/articles/10589769-authenticating-users-in-the-messenger-with-json-web-tokens-jwts
  • intercom/tags/3.0.0/test/IntercomSettingsPageTest.php

    r3036264 r3272615  
    11<?php
    2 class IntercomSettingsPageTest extends PHPUnit_Framework_TestCase
     2use PHPUnit\Framework\TestCase;
     3use PHPUnit\Framework\MockObject\MockObject;
     4
     5class IntercomSettingsPageTest extends TestCase
    36{
    4   public function testSkip()
    5   {
     7  private $settings;
     8  private $intercomSettingsPage;
     9  private $originalGet;
     10
     11  protected function setUp(): void
     12  {
     13    parent::setUp();
     14   
     15    // Store original $_GET
     16    $this->originalGet = $_GET;
     17   
     18    // Default settings
     19    $this->settings = [
     20      'app_id' => 'test_app_id',
     21      'secret' => 'test_secret',
     22      'identity_verification' => false
     23    ];
     24   
     25    // Create the IntercomSettingsPage instance
     26    $this->intercomSettingsPage = new IntercomSettingsPage($this->settings);
     27  }
     28
     29  protected function tearDown(): void
     30  {
     31    // Restore original $_GET
     32    $_GET = $this->originalGet;
     33   
     34    parent::tearDown();
     35  }
     36
     37  /**
     38   * Test the constructor properly initializes the class
     39   */
     40  public function testConstructor()
     41  {
     42    $settings = [
     43      'app_id' => 'test_app_id',
     44      'secret' => 'test_secret',
     45      'identity_verification' => true
     46    ];
     47   
     48    $intercomSettingsPage = new IntercomSettingsPage($settings);
     49   
     50    // Use reflection to access private properties
     51    $reflection = new ReflectionClass($intercomSettingsPage);
     52    $settingsProperty = $reflection->getProperty('settings');
     53    $settingsProperty->setAccessible(true);
     54    $stylesProperty = $reflection->getProperty('styles');
     55    $stylesProperty->setAccessible(true);
     56   
     57    $this->assertEquals($settings, $settingsProperty->getValue($intercomSettingsPage));
     58    $this->assertNotEmpty($stylesProperty->getValue($intercomSettingsPage));
     59  }
     60
     61  /**
     62   * Test the dismissibleMessage method
     63   */
     64  public function testDismissibleMessage()
     65  {
     66    $message = "Test message";
     67    $result = $this->intercomSettingsPage->dismissibleMessage($message);
     68   
     69    $this->assertStringContainsString('<div id="message" class="updated notice is-dismissible">', $result);
     70    $this->assertStringContainsString('<p>' . $message . '</p>', $result);
     71    $this->assertStringContainsString('<button type="button" class="notice-dismiss">', $result);
     72  }
     73
     74  /**
     75   * Test the getAuthUrl method
     76   */
     77  public function testGetAuthUrl()
     78  {
     79    // Mock WordPress functions
     80    if (!function_exists('get_site_url')) {
     81      function get_site_url() {
     82        return 'https://example.com';
     83      }
     84    }
     85   
     86    if (!function_exists('wp_create_nonce')) {
     87      function wp_create_nonce($action) {
     88        return 'test_nonce';
     89      }
     90    }
     91   
     92    $authUrl = $this->intercomSettingsPage->getAuthUrl();
     93   
     94    $this->assertStringContainsString('https://wordpress_auth.intercom.io/confirm?state=', $authUrl);
     95    $this->assertStringContainsString('https://example.com', $authUrl);
     96    $this->assertStringContainsString('test_nonce', $authUrl);
     97  }
     98
     99  /**
     100   * Test the htmlUnclosed method with different GET parameters
     101   */
     102  public function testHtmlUnclosed()
     103  {
     104    // Test with appId parameter
     105    $_GET['appId'] = 'new_app_id';
     106    $html = $this->intercomSettingsPage->htmlUnclosed();
     107    $this->assertStringContainsString('new_app_id', $html);
     108    $this->assertStringContainsString("We've copied your new Intercom app id below", $html);
     109   
     110    // Test with saved parameter
     111    $_GET = [];
     112    $_GET['saved'] = true;
     113    $html = $this->intercomSettingsPage->htmlUnclosed();
     114    $this->assertStringContainsString("Your app id has been successfully saved", $html);
     115   
     116    // Test with authenticated parameter
     117    $_GET = [];
     118    $_GET['authenticated'] = true;
     119    $html = $this->intercomSettingsPage->htmlUnclosed();
     120    $this->assertStringContainsString("You successfully authenticated with Intercom", $html);
     121  }
     122
     123  /**
     124   * Test the htmlClosed method
     125   */
     126  public function testHtmlClosed()
     127  {
     128    $html = $this->intercomSettingsPage->htmlClosed();
     129   
     130    $this->assertStringContainsString('</form>', $html);
     131    $this->assertStringContainsString('Identity Verification', $html);
     132    $this->assertStringContainsString('https://docs.intercom.com', $html);
     133  }
     134
     135  /**
     136   * Test the html method
     137   */
     138  public function testHtml()
     139  {
     140    $html = $this->intercomSettingsPage->html();
     141   
     142    $this->assertStringContainsString('<div class="wrap">', $html);
     143    $this->assertStringContainsString('</div>', $html);
     144    $this->assertStringContainsString('https://code.jquery.com/jquery-2.2.0.min.js', $html);
     145  }
     146
     147  /**
     148   * Test the setStyles method with different settings
     149   */
     150  public function testSetStyles()
     151  {
     152    // Test with identity verification enabled
     153    $settings = [
     154      'app_id' => 'test_app_id',
     155      'secret' => 'test_secret',
     156      'identity_verification' => true
     157    ];
     158   
     159    $intercomSettingsPage = new IntercomSettingsPage($settings);
     160    $reflection = new ReflectionClass($intercomSettingsPage);
     161    $stylesProperty = $reflection->getProperty('styles');
     162    $stylesProperty->setAccessible(true);
     163   
     164    $styles = $stylesProperty->getValue($intercomSettingsPage);
     165    $this->assertEquals('checked disabled', $styles['identity_verification_state']);
     166   
     167    // Test with app_id but no secret
     168    $settings = [
     169      'app_id' => 'test_app_id',
     170      'secret' => '',
     171      'identity_verification' => false
     172    ];
     173   
     174    $intercomSettingsPage = new IntercomSettingsPage($settings);
     175    $styles = $stylesProperty->getValue($intercomSettingsPage);
     176    $this->assertEquals('display: none;', $styles['app_secret_row_style']);
     177    $this->assertEquals('', $styles['app_secret_link_style']);
     178   
     179    // Test with appId in GET
     180    $_GET['appId'] = 'new_app_id';
     181    $intercomSettingsPage = new IntercomSettingsPage($settings);
     182    $styles = $stylesProperty->getValue($intercomSettingsPage);
     183    $this->assertEquals('readonly', $styles['app_id_state']);
     184    $this->assertEquals('cta__email', $styles['app_id_class']);
     185    $this->assertEquals('', $styles['button_submit_style']);
     186    $this->assertEquals('display: none;', $styles['app_id_copy_hidden']);
     187   
     188    // Test with saved in GET
     189    $_GET = [];
     190    $_GET['saved'] = true;
     191    $intercomSettingsPage = new IntercomSettingsPage($settings);
     192    $styles = $stylesProperty->getValue($intercomSettingsPage);
     193    $this->assertEquals('display: none;', $styles['app_id_copy_hidden']);
     194    $this->assertEquals('', $styles['app_id_saved_title']);
     195   
     196    // Test with empty app_id
     197    $settings = [
     198      'app_id' => '',
     199      'secret' => 'test_secret',
     200      'identity_verification' => false
     201    ];
     202   
     203    $intercomSettingsPage = new IntercomSettingsPage($settings);
     204    $styles = $stylesProperty->getValue($intercomSettingsPage);
     205    $this->assertEquals('display: none;', $styles['app_id_row_style']);
     206    $this->assertEquals('', $styles['app_id_link_style']);
     207  }
     208
     209  /**
     210   * Test the getSettings method
     211   */
     212  public function testGetSettings()
     213  {
     214    $reflection = new ReflectionClass($this->intercomSettingsPage);
     215    $method = $reflection->getMethod('getSettings');
     216    $method->setAccessible(true);
     217   
     218    $settings = $method->invoke($this->intercomSettingsPage);
     219   
     220    $this->assertEquals($this->settings, $settings);
     221  }
     222
     223  /**
     224   * Test the getStyles method
     225   */
     226  public function testGetStyles()
     227  {
     228    $reflection = new ReflectionClass($this->intercomSettingsPage);
     229    $method = $reflection->getMethod('getStyles');
     230    $method->setAccessible(true);
     231   
     232    $styles = $method->invoke($this->intercomSettingsPage);
     233   
     234    $this->assertNotEmpty($styles);
     235    $this->assertIsArray($styles);
    6236  }
    7237}
  • intercom/tags/3.0.0/test/SecureModeCalculatorTest.php

    r3036264 r3272615  
    11<?php
    2 class IdentityVerificationCalculatorTest extends PHPUnit_Framework_TestCase
     2
     3use PHPUnit\Framework\TestCase;
     4use Firebase\JWT\JWT;
     5
     6class MessengerSecurityCalculatorTest extends TestCase
    37{
    4   public function testHashEmail()
     8  protected function setUp(): void
    59  {
    6     $data = array("email" => "[email protected]");
    7     $calculator = new IdentityVerificationCalculator($data, "s3cre7");
    8     $this->assertEquals(array("user_hash" => "844240a2deab99438ade8e7477aa832e22adb0e1eb1ad7754ff8d4054fb63869"), $calculator->identityVerificationComponent());
     10    parent::setUp();
     11    // Freeze time to a specific timestamp
     12    TimeProvider::setMockTime(strtotime('2024-04-08 12:00:00'));
    913  }
    1014
    11   public function testHashUserId()
     15  protected function tearDown(): void
    1216  {
    13     $data = array("user_id" => "abcdef", "email" => "[email protected]");
    14     $calculator = new IdentityVerificationCalculator($data, "s3cre7");
    15     $this->assertEquals(array("user_hash" => "532cd9cd6bfa49528cf2503db0743bb72456bda2cb7424d2894c5b11f6cad6cf"), $calculator->identityVerificationComponent());
     17    TimeProvider::resetMockTime();
     18    parent::tearDown();
     19  }
     20
     21  public function testEmailJWT()
     22  {
     23    $data = array("app_id" => "abcdef", "email" => "[email protected]");
     24    $calculator = new MessengerSecurityCalculator($data, "s3cre7");
     25    $jwt_data = array(
     26      "user_id" => "[email protected]",
     27      "email" => "[email protected]",
     28      "exp" => TimeProvider::getCurrentTime() + 3600
     29    );
     30    $jwt = JWT::encode($jwt_data, "s3cre7", 'HS256');
     31    $this->assertEquals(
     32      array(
     33        "app_id" => "abcdef",
     34        "intercom_user_jwt" => $jwt
     35      ),
     36      $calculator->messengerSecurityComponent()
     37    );
     38  }
     39
     40  public function testUserIdEmailJWT()
     41  {
     42    $data = array("app_id" => "abcdef", "user_id" => "abcdef", "email" => "[email protected]");
     43    $calculator = new MessengerSecurityCalculator($data, "s3cre7");
     44    $jwt_data = array(
     45      "user_id" => "abcdef",
     46      "email" => "[email protected]",
     47      "exp" => TimeProvider::getCurrentTime() + 3600
     48    );
     49    $jwt = JWT::encode($jwt_data, "s3cre7", 'HS256');
     50    $this->assertEquals(
     51      array(
     52        "app_id" => "abcdef",
     53        "intercom_user_jwt" => $jwt
     54      ),
     55      $calculator->messengerSecurityComponent()
     56    );
     57  }
     58
     59  public function testUserIdEmailNameJWT()
     60  {
     61    $data = array("app_id" => "abcdef", "user_id" => "abcdef", "email" => "[email protected]", "name" => "John Doe");
     62    $calculator = new MessengerSecurityCalculator($data, "s3cre7");
     63    $jwt_data = array(
     64      "user_id" => "abcdef",
     65      "email" => "[email protected]",
     66      "name" => "John Doe",
     67      "exp" => TimeProvider::getCurrentTime() + 3600
     68    );
     69    $jwt = JWT::encode($jwt_data, "s3cre7", 'HS256');
     70    $this->assertEquals(
     71      array(
     72        "app_id" => "abcdef",
     73        "intercom_user_jwt" => $jwt
     74      ),
     75      $calculator->messengerSecurityComponent()
     76    );
    1677  }
    1778
    1879  public function testEmpty()
    1980  {
    20     $data = array();
    21     $calculator = new IdentityVerificationCalculator($data, "s3cre7");
    22     $this->assertEquals(array(), $calculator->identityVerificationComponent());
     81    $data = array("app_id" => "abcdef");
     82    $calculator = new MessengerSecurityCalculator($data, "s3cre7");
     83    $this->assertEquals(
     84      array(
     85        "app_id" => "abcdef",
     86      ),
     87      $calculator->messengerSecurityComponent()
     88    );
     89  }
     90
     91  public function testExtraJWTData()
     92  {
     93    putenv('INTERCOM_PLUGIN_TEST_JWT_DATA=' . json_encode(array("custom_data" => "custom_value")));
     94
     95    $data = array("app_id" => "abcdef", "user_id" => "abcdef", "email" => "[email protected]", "name" => "John Doe");
     96    $calculator = new MessengerSecurityCalculator($data, "s3cre7");
     97    $jwt_data = array(
     98      "user_id" => "abcdef",
     99      "email" => "[email protected]",
     100      "name" => "John Doe",
     101      "custom_data" => "custom_value",
     102      "exp" => TimeProvider::getCurrentTime() + 3600
     103    );
     104    $jwt = JWT::encode($jwt_data, "s3cre7", 'HS256');
     105    $this->assertEquals(
     106      array(
     107        "app_id" => "abcdef",
     108        "intercom_user_jwt" => $jwt
     109      ),
     110      $calculator->messengerSecurityComponent()
     111    );
     112    putenv('INTERCOM_PLUGIN_TEST_JWT_DATA=');
    23113  }
    24114}
  • intercom/tags/3.0.0/test/SnippetSettingsTest.php

    r3036264 r3272615  
    55}
    66
    7 class IntercomSnippetSettingsTest extends PHPUnit_Framework_TestCase
     7use PHPUnit\Framework\TestCase;
     8use PHPUnit\Framework\MockObject\MockObject;
     9use Firebase\JWT\JWT;
     10
     11class IntercomSnippetSettingsTest extends TestCase
    812{
     13  protected function setUp(): void
     14  {
     15    parent::setUp();
     16    // Freeze time to a specific timestamp
     17    TimeProvider::setMockTime(strtotime('2024-04-08 12:00:00'));
     18  }
     19
     20  protected function tearDown(): void
     21  {
     22    TimeProvider::resetMockTime();
     23    parent::tearDown();
     24  }
     25
    926  public function testJSONRendering()
    1027  {
     
    1431  public function testJSONRenderingWithIdentityVerification()
    1532  {
    16     $snippet_settings = new IntercomSnippetSettings(array("app_id" => "bar"), "foo", new FakeWordPressUserForSnippetTest());
    17     $this->assertEquals("{\"app_id\":\"bar\",\"email\":\"[email protected]\",\"user_hash\":\"a95b0a1ab461c0721d91fbe32a5f5f2a27ac0bfa4bfbcfced168173fa80d4e14\",\"installation_type\":\"wordpress\"}", $snippet_settings->json());
     33    $snippet_settings = new IntercomSnippetSettings(array("app_id" => "bar"), "s3cre7", new FakeWordPressUserForSnippetTest());
     34    $jwt_data = array(
     35      "user_id" => "[email protected]",
     36      "email" => "[email protected]",
     37      "exp" => TimeProvider::getCurrentTime() + 3600
     38    );
     39    $jwt = JWT::encode($jwt_data, "s3cre7", 'HS256');
     40    $this->assertEquals('{"app_id":"bar","intercom_user_jwt":"'.$jwt.'","installation_type":"wordpress"}', $snippet_settings->json());
    1841  }
    1942  public function testJSONRenderingWithIdentityVerificationAndNoSecret()
     
    4063  }
    4164
    42   /**
    43   * @expectedException Exception
    44   */
    4565  public function testValidation()
    4666  {
     67    $this->expectException(\Exception::class);
    4768    $snippet = new IntercomSnippetSettings(array("foo" => "bar"));
    4869  }
  • intercom/tags/3.0.0/test/SnippetTest.php

    r3036264 r3272615  
    11<?php
    2 class IntercomSnippetTest extends PHPUnit_Framework_TestCase
     2use PHPUnit\Framework\TestCase;
     3
     4class IntercomSnippetTest extends TestCase
    35{
    46  public function testGeneratedHtml()
  • intercom/tags/3.0.0/test/UserTest.php

    r1622875 r3272615  
    99}
    1010
    11 class UserTest extends PHPUnit_Framework_TestCase
     11use PHPUnit\Framework\TestCase;
     12
     13class UserTest extends TestCase
    1214{
    1315  public function testEmail()
  • intercom/tags/3.0.0/test/ValidatorTest.php

    r1622875 r3272615  
    11<?php
    2 class ValidatorTest extends PHPUnit_Framework_TestCase
     2use PHPUnit\Framework\TestCase;
     3
     4class ValidatorTest extends TestCase
    35{
    46  public function testValidator()
  • intercom/trunk/bootstrap.php

    r3036274 r3272615  
    66Author: Intercom
    77Author URI: https://www.intercom.io
    8 Version: 2.6.6
     8Version: 3.0.0
    99 */
    1010
    11 class IdentityVerificationCalculator
     11require_once __DIR__ . '/vendor/autoload.php';
     12use Firebase\JWT\JWT;
     13
     14class TimeProvider
     15{
     16    private static $mockTime = null;
     17
     18    public static function setMockTime($timestamp)
     19    {
     20        self::$mockTime = $timestamp;
     21    }
     22
     23    public static function resetMockTime()
     24    {
     25        self::$mockTime = null;
     26    }
     27
     28    public static function getCurrentTime()
     29    {
     30        return self::$mockTime !== null ? self::$mockTime : time();
     31    }
     32}
     33
     34class MessengerSecurityCalculator
    1235{
    1336  private $raw_data = array();
     
    2043  }
    2144
    22   public function identityVerificationComponent()
     45  public function messengerSecurityComponent()
    2346  {
    2447    $secret_key = $this->getSecretKey();
     48
    2549    if (empty($secret_key))
    2650    {
    27       return $this->emptyIdentityVerificationHashComponent();
    28     }
    29     if (array_key_exists("user_id", $this->getRawData()))
    30     {
    31       return $this->identityVerificationHashComponent("user_id");
    32     }
    33     if (array_key_exists("email", $this->getRawData()))
    34     {
    35       return $this->identityVerificationHashComponent("email");
    36     }
    37     return $this->emptyIdentityVerificationHashComponent();
    38   }
    39 
    40   private function emptyIdentityVerificationHashComponent()
    41   {
    42     return array();
    43   }
    44 
    45   private function identityVerificationHashComponent($key)
     51      return $this->getRawData();
     52    }
     53    if (array_key_exists("user_id", $this->getRawData()) || array_key_exists("email", $this->getRawData()))
     54    {
     55      return $this->messengerSecurityJWTComponent();
     56    }
     57
     58    return $this->getRawData();
     59  }
     60
     61  private function messengerSecurityJWTComponent()
    4662  {
    4763    $raw_data = $this->getRawData();
    48     return array("user_hash" => hash_hmac("sha256", $raw_data[$key], $this->getSecretKey()));
     64
     65    $filtered_data = $raw_data;
     66    $payload = array();
     67
     68    if (array_key_exists("email", $filtered_data)) {
     69      unset($filtered_data["email"]);
     70      $payload["user_id"] = $raw_data["email"];
     71      $payload["email"] = $raw_data["email"];
     72    }
     73    if (array_key_exists("user_id", $filtered_data)) {
     74      unset($filtered_data["user_id"]);
     75      $payload["user_id"] = $raw_data["user_id"];
     76    }
     77    if (array_key_exists("name", $filtered_data)) {
     78      unset($filtered_data["name"]);
     79      $payload["name"] = $raw_data["name"];
     80    }
     81
     82    $payload = array_merge($payload, apply_filters("intercom_sensitive_attributes", array()));
     83    $payload["exp"] = TimeProvider::getCurrentTime() + 3600;
     84
     85    $filtered_data["intercom_user_jwt"] = JWT::encode(
     86      $payload, $this->getSecretKey(),
     87      'HS256'
     88    );
     89
     90    return $filtered_data;
    4991  }
    5092
     
    5395    return $this->secret_key;
    5496  }
     97
    5598  private function getRawData()
    5699  {
     
    195238                    </p>
    196239                    <br/>
    197                     <div style="font-size:0.8em">If the Intercom application associated with your Wordpress is incorrect, please <a class="c__blue" href="$auth_url">click here</a> to reconnect with Intercom, to choose a new application.</div>
     240                    <div style="font-size:0.8em">If the Intercom application associated with your WordPress is incorrect, please <a class="c__blue" href="$auth_url">click here</a> to reconnect with Intercom, to choose a new application.</div>
    198241                  </div>
    199242                </div>
     
    358401  {
    359402    $user = new IntercomUser($this->wordpress_user, $this->raw_data);
    360     $settings = apply_filters("intercom_settings", $user->buildSettings());
    361     $identityVerificationCalculator = new IdentityVerificationCalculator($settings, $this->secret);
    362     $result = array_merge($settings, $identityVerificationCalculator->identityVerificationComponent());
    363     $result = $this->mergeConstants($result);
     403    $messengerSecurityCalculator = new MessengerSecurityCalculator($user->buildSettings(), $this->secret);
     404    $settings = $messengerSecurityCalculator->messengerSecurityComponent();
     405    $result = $this->mergeConstants(apply_filters("intercom_settings", $settings));
    364406    $result['installation_type'] = 'wordpress';
    365407    return $result;
     
    386428
    387429if (getenv('INTERCOM_PLUGIN_TEST') == '1' && !function_exists('apply_filters')) {
    388   function apply_filters($_, $value) {
     430  function apply_filters($key, $value) {
     431    if ($key == "intercom_sensitive_attributes") {
     432      $extra_data_key = 'INTERCOM_PLUGIN_TEST_JWT_DATA';
     433    } elseif ($key == "intercom_settings") {
     434      $extra_data_key = 'INTERCOM_PLUGIN_TEST_SETTINGS';
     435    }
     436
     437    $extra_data = getenv($extra_data_key);
     438    if ($extra_data) {
     439      $extra_data = json_decode($extra_data, true);
     440      return array_merge($value, $extra_data);
     441    }
     442
    389443    return $value;
    390444  }
     
    436490    {
    437491      $this->settings["email"] = WordPressEscaper::escJS($this->wordpress_user->user_email);
     492    }
     493    if (!empty($this->wordpress_user->ID))
     494    {
     495      $this->settings["user_id"] = WordPressEscaper::escJS($this->wordpress_user->ID);
    438496    }
    439497    if (!empty($this->wordpress_user->display_name))
  • intercom/trunk/readme.md

    r1759316 r3272615  
    55# Compatibility
    66
    7 Requires PHP 5.6 or higher.
     7Requires PHP 7.2 or higher.
    88
    99# Local Testing
     
    1414INTERCOM_PLUGIN_TEST=1 phpunit
    1515```
    16 
    17 # Test the new version of the plugin with Intercom's Wordpress signup flow
    18 
    19 It is mandatory that you fully test the [intercom wordpress setup guide](https://app.intercom.io/a/start/wordpress) before you release a new update of the plugin.
    2016
    2117# Usage
     
    3127NB: This plugin injects a Javascript snippet on your website frontend containing dynamic user data. Some caching solutions will cache entire pages and should not be used with this plugin. Doing so may cause conversations to be delivered to the wrong user.
    3228
    33 # Pass extra parameters to the Intercom Messenger
     29# Pass custom data attributes to the Intercom Messenger
    3430
    35 Using the [Wordpress Hooks API](https://codex.wordpress.org/Plugin_API) `add_filter` method in your Wordpress theme you can pass extra parameters to the Intercom Messenger (see example below):
     31Using the [add_filter](https://developer.wordpress.org/reference/functions/add_filter) method in your WordPress theme or custom plugin you can pass [custom data attributes](https://www.intercom.com/help/en/articles/179-create-and-track-custom-data-attributes-cdas) to the Intercom Messenger (see example below):
    3632
    3733```php
    38 add_filter( 'intercom_settings', function( $settings ) {                                                 
    39   $settings['user_id'] = $user_id;               
    40   return $settings;                                                     
     34add_filter( 'intercom_settings', function( $settings ) {
     35  $settings['customer_type'] = $customer_type;
     36  return $settings;
    4137} );
    4238```
     
    4541# Users
    4642
    47 If a `$current_user` is present, we use their email as an identifier in the widget.
     43If a `$current_user` is present, we use their email and ID as an identifier in the widget.
    4844We recommend enabling [Identity Verification](https://docs.intercom.com/configure-intercom-for-your-product-or-site/staying-secure/enable-identity-verification-on-your-web-product) in the settings page.
    4945
  • intercom/trunk/readme.txt

    r3036264 r3272615  
    1 === Plugin Name ===
    2 Contributors: bobintercom
     1=== Intercom ===
     2Contributors: bobintercom, jacopointercom
     3Tags: intercom, ai, customer, chat
     4Requires at least: 4.7.0
     5Tested up to: 6.7.2
     6Requires PHP: 7.2
    37License: Apache 2.0
    4 Tags: intercom, customer, chat
    5 Requires at least: 4.2.0
    6 Tested up to: 6.4.3
     8Stable tag: 3.0
    79
    8 The official WordPress plugin, built by Intercom.
    9 
    10 Chat with visitors to your website in real-time, capture them as leads, and convert them to customers.
     10Official Intercom WordPress plugin: Engage visitors in real time, power growth with AI, and convert leads into loyal customers.
    1111
    1212== Description ==
    1313
    14 [Intercom](https://www.intercom.io/) is a fundamentally new way for internet businesses to communicate with customers, personally, at scale. It's a customer communication platform with a suite of integrated products for every team – including sales, marketing, product, and support. Our products enable targeted communication with customers on your website, inside your web and mobile apps, and by email.
     14[Intercom](https://www.intercom.com/) is a next-generation customer communications platform that combines powerful live chat, proactive messaging, and advanced AI solutions — like our Fin AI chatbot — to help businesses instantly connect with customers.
    1515
    16 With this plugin, you can add the Intercom Messenger to your website in just a few clicks and start chatting to customers and visitors to your website right away.
    17 
    18 Your logged-in customers will be tracked in Intercom as users, and visitors who aren’t customers (or aren’t logged in) will be tracked as leads.
     16By installing the Intercom WordPress plugin, you can seamlessly add the Messenger to your site, track both logged-in users and visitors, and engage them right away. With Intercom’s industry-leading AI at your fingertips, you’ll deliver fast, personalized support and drive growth more effectively than ever before.
    1917
    2018== Installation ==
     
    2220Installing Intercom on your WordPress site takes just a few minutes.
    2321
    24 You can find full instructions on signing up and installing Intercom using the WordPress plugin [here](https://docs.intercom.io/install-on-your-product-or-site/other-ways-to-get-started/install-intercom-on-your-wordpress-site).
     22You can find full instructions on signing up and installing Intercom using the WordPress plugin [here](https://www.intercom.com/help/en/articles/173-install-intercom-on-your-wordpress-site).
    2523
    26 If you’re already an Intercom customer, you can also find instructions in the in-app [setup guide](https://app.intercom.com/a/apps/_/platform/guide) or [app store](https://app.intercom.com/a/apps/_/appstore?app_package_code=wordpress&search=wordpress). The first thing you’ll need to do is install and activate the plugin - you must be using WordPress v4.2.0 or higher and have the ability to install plugins in order to use this method.
     24If you’re already an Intercom customer, you can also find instructions in the in-app [setup guide](https://app.intercom.com/a/apps/_/platform/guide) or [app store](https://app.intercom.com/a/apps/_/appstore?app_package_code=wordpress&search=wordpress).
     25
     26The first thing you’ll need to do is install and activate the plugin - you must be using WordPress v4.9.0 or higher and have the ability to install plugins in order to use this method.
    2727
    2828Note: This plugin injects a Javascript snippet on your website frontend containing dynamic user data. Some caching solutions will cache entire pages and should not be used with this plugin. Doing so may cause conversations to be delivered to the wrong user.
     29
     30== Screenshots ==
     311. Plugin settings authenticate with Intercom settings_not_auth.png
     322. Plugin settings successfully authenticated with Intercom settings_auth.png
     333. Intercom widget used by customers to communicate with the business widget.png
     34== Changelog ==
     35
     36= 3.0 =
     37* Replaced user_hash with intercom_user_jwt https://www.intercom.com/help/en/articles/10589769-authenticating-users-in-the-messenger-with-json-web-tokens-jwts.
     38* Updated readme to follow guidelines.
     39* Added missing tests.
     40
     41== Upgrade Notice ==
     42
     43= 3.0 =
     44Upgrade the security of your messenger with the introduction of JWT - https://www.intercom.com/help/en/articles/10589769-authenticating-users-in-the-messenger-with-json-web-tokens-jwts
  • intercom/trunk/test/IntercomSettingsPageTest.php

    r3036264 r3272615  
    11<?php
    2 class IntercomSettingsPageTest extends PHPUnit_Framework_TestCase
     2use PHPUnit\Framework\TestCase;
     3use PHPUnit\Framework\MockObject\MockObject;
     4
     5class IntercomSettingsPageTest extends TestCase
    36{
    4   public function testSkip()
    5   {
     7  private $settings;
     8  private $intercomSettingsPage;
     9  private $originalGet;
     10
     11  protected function setUp(): void
     12  {
     13    parent::setUp();
     14   
     15    // Store original $_GET
     16    $this->originalGet = $_GET;
     17   
     18    // Default settings
     19    $this->settings = [
     20      'app_id' => 'test_app_id',
     21      'secret' => 'test_secret',
     22      'identity_verification' => false
     23    ];
     24   
     25    // Create the IntercomSettingsPage instance
     26    $this->intercomSettingsPage = new IntercomSettingsPage($this->settings);
     27  }
     28
     29  protected function tearDown(): void
     30  {
     31    // Restore original $_GET
     32    $_GET = $this->originalGet;
     33   
     34    parent::tearDown();
     35  }
     36
     37  /**
     38   * Test the constructor properly initializes the class
     39   */
     40  public function testConstructor()
     41  {
     42    $settings = [
     43      'app_id' => 'test_app_id',
     44      'secret' => 'test_secret',
     45      'identity_verification' => true
     46    ];
     47   
     48    $intercomSettingsPage = new IntercomSettingsPage($settings);
     49   
     50    // Use reflection to access private properties
     51    $reflection = new ReflectionClass($intercomSettingsPage);
     52    $settingsProperty = $reflection->getProperty('settings');
     53    $settingsProperty->setAccessible(true);
     54    $stylesProperty = $reflection->getProperty('styles');
     55    $stylesProperty->setAccessible(true);
     56   
     57    $this->assertEquals($settings, $settingsProperty->getValue($intercomSettingsPage));
     58    $this->assertNotEmpty($stylesProperty->getValue($intercomSettingsPage));
     59  }
     60
     61  /**
     62   * Test the dismissibleMessage method
     63   */
     64  public function testDismissibleMessage()
     65  {
     66    $message = "Test message";
     67    $result = $this->intercomSettingsPage->dismissibleMessage($message);
     68   
     69    $this->assertStringContainsString('<div id="message" class="updated notice is-dismissible">', $result);
     70    $this->assertStringContainsString('<p>' . $message . '</p>', $result);
     71    $this->assertStringContainsString('<button type="button" class="notice-dismiss">', $result);
     72  }
     73
     74  /**
     75   * Test the getAuthUrl method
     76   */
     77  public function testGetAuthUrl()
     78  {
     79    // Mock WordPress functions
     80    if (!function_exists('get_site_url')) {
     81      function get_site_url() {
     82        return 'https://example.com';
     83      }
     84    }
     85   
     86    if (!function_exists('wp_create_nonce')) {
     87      function wp_create_nonce($action) {
     88        return 'test_nonce';
     89      }
     90    }
     91   
     92    $authUrl = $this->intercomSettingsPage->getAuthUrl();
     93   
     94    $this->assertStringContainsString('https://wordpress_auth.intercom.io/confirm?state=', $authUrl);
     95    $this->assertStringContainsString('https://example.com', $authUrl);
     96    $this->assertStringContainsString('test_nonce', $authUrl);
     97  }
     98
     99  /**
     100   * Test the htmlUnclosed method with different GET parameters
     101   */
     102  public function testHtmlUnclosed()
     103  {
     104    // Test with appId parameter
     105    $_GET['appId'] = 'new_app_id';
     106    $html = $this->intercomSettingsPage->htmlUnclosed();
     107    $this->assertStringContainsString('new_app_id', $html);
     108    $this->assertStringContainsString("We've copied your new Intercom app id below", $html);
     109   
     110    // Test with saved parameter
     111    $_GET = [];
     112    $_GET['saved'] = true;
     113    $html = $this->intercomSettingsPage->htmlUnclosed();
     114    $this->assertStringContainsString("Your app id has been successfully saved", $html);
     115   
     116    // Test with authenticated parameter
     117    $_GET = [];
     118    $_GET['authenticated'] = true;
     119    $html = $this->intercomSettingsPage->htmlUnclosed();
     120    $this->assertStringContainsString("You successfully authenticated with Intercom", $html);
     121  }
     122
     123  /**
     124   * Test the htmlClosed method
     125   */
     126  public function testHtmlClosed()
     127  {
     128    $html = $this->intercomSettingsPage->htmlClosed();
     129   
     130    $this->assertStringContainsString('</form>', $html);
     131    $this->assertStringContainsString('Identity Verification', $html);
     132    $this->assertStringContainsString('https://docs.intercom.com', $html);
     133  }
     134
     135  /**
     136   * Test the html method
     137   */
     138  public function testHtml()
     139  {
     140    $html = $this->intercomSettingsPage->html();
     141   
     142    $this->assertStringContainsString('<div class="wrap">', $html);
     143    $this->assertStringContainsString('</div>', $html);
     144    $this->assertStringContainsString('https://code.jquery.com/jquery-2.2.0.min.js', $html);
     145  }
     146
     147  /**
     148   * Test the setStyles method with different settings
     149   */
     150  public function testSetStyles()
     151  {
     152    // Test with identity verification enabled
     153    $settings = [
     154      'app_id' => 'test_app_id',
     155      'secret' => 'test_secret',
     156      'identity_verification' => true
     157    ];
     158   
     159    $intercomSettingsPage = new IntercomSettingsPage($settings);
     160    $reflection = new ReflectionClass($intercomSettingsPage);
     161    $stylesProperty = $reflection->getProperty('styles');
     162    $stylesProperty->setAccessible(true);
     163   
     164    $styles = $stylesProperty->getValue($intercomSettingsPage);
     165    $this->assertEquals('checked disabled', $styles['identity_verification_state']);
     166   
     167    // Test with app_id but no secret
     168    $settings = [
     169      'app_id' => 'test_app_id',
     170      'secret' => '',
     171      'identity_verification' => false
     172    ];
     173   
     174    $intercomSettingsPage = new IntercomSettingsPage($settings);
     175    $styles = $stylesProperty->getValue($intercomSettingsPage);
     176    $this->assertEquals('display: none;', $styles['app_secret_row_style']);
     177    $this->assertEquals('', $styles['app_secret_link_style']);
     178   
     179    // Test with appId in GET
     180    $_GET['appId'] = 'new_app_id';
     181    $intercomSettingsPage = new IntercomSettingsPage($settings);
     182    $styles = $stylesProperty->getValue($intercomSettingsPage);
     183    $this->assertEquals('readonly', $styles['app_id_state']);
     184    $this->assertEquals('cta__email', $styles['app_id_class']);
     185    $this->assertEquals('', $styles['button_submit_style']);
     186    $this->assertEquals('display: none;', $styles['app_id_copy_hidden']);
     187   
     188    // Test with saved in GET
     189    $_GET = [];
     190    $_GET['saved'] = true;
     191    $intercomSettingsPage = new IntercomSettingsPage($settings);
     192    $styles = $stylesProperty->getValue($intercomSettingsPage);
     193    $this->assertEquals('display: none;', $styles['app_id_copy_hidden']);
     194    $this->assertEquals('', $styles['app_id_saved_title']);
     195   
     196    // Test with empty app_id
     197    $settings = [
     198      'app_id' => '',
     199      'secret' => 'test_secret',
     200      'identity_verification' => false
     201    ];
     202   
     203    $intercomSettingsPage = new IntercomSettingsPage($settings);
     204    $styles = $stylesProperty->getValue($intercomSettingsPage);
     205    $this->assertEquals('display: none;', $styles['app_id_row_style']);
     206    $this->assertEquals('', $styles['app_id_link_style']);
     207  }
     208
     209  /**
     210   * Test the getSettings method
     211   */
     212  public function testGetSettings()
     213  {
     214    $reflection = new ReflectionClass($this->intercomSettingsPage);
     215    $method = $reflection->getMethod('getSettings');
     216    $method->setAccessible(true);
     217   
     218    $settings = $method->invoke($this->intercomSettingsPage);
     219   
     220    $this->assertEquals($this->settings, $settings);
     221  }
     222
     223  /**
     224   * Test the getStyles method
     225   */
     226  public function testGetStyles()
     227  {
     228    $reflection = new ReflectionClass($this->intercomSettingsPage);
     229    $method = $reflection->getMethod('getStyles');
     230    $method->setAccessible(true);
     231   
     232    $styles = $method->invoke($this->intercomSettingsPage);
     233   
     234    $this->assertNotEmpty($styles);
     235    $this->assertIsArray($styles);
    6236  }
    7237}
  • intercom/trunk/test/SecureModeCalculatorTest.php

    r3036264 r3272615  
    11<?php
    2 class IdentityVerificationCalculatorTest extends PHPUnit_Framework_TestCase
     2
     3use PHPUnit\Framework\TestCase;
     4use Firebase\JWT\JWT;
     5
     6class MessengerSecurityCalculatorTest extends TestCase
    37{
    4   public function testHashEmail()
     8  protected function setUp(): void
    59  {
    6     $data = array("email" => "[email protected]");
    7     $calculator = new IdentityVerificationCalculator($data, "s3cre7");
    8     $this->assertEquals(array("user_hash" => "844240a2deab99438ade8e7477aa832e22adb0e1eb1ad7754ff8d4054fb63869"), $calculator->identityVerificationComponent());
     10    parent::setUp();
     11    // Freeze time to a specific timestamp
     12    TimeProvider::setMockTime(strtotime('2024-04-08 12:00:00'));
    913  }
    1014
    11   public function testHashUserId()
     15  protected function tearDown(): void
    1216  {
    13     $data = array("user_id" => "abcdef", "email" => "[email protected]");
    14     $calculator = new IdentityVerificationCalculator($data, "s3cre7");
    15     $this->assertEquals(array("user_hash" => "532cd9cd6bfa49528cf2503db0743bb72456bda2cb7424d2894c5b11f6cad6cf"), $calculator->identityVerificationComponent());
     17    TimeProvider::resetMockTime();
     18    parent::tearDown();
     19  }
     20
     21  public function testEmailJWT()
     22  {
     23    $data = array("app_id" => "abcdef", "email" => "[email protected]");
     24    $calculator = new MessengerSecurityCalculator($data, "s3cre7");
     25    $jwt_data = array(
     26      "user_id" => "[email protected]",
     27      "email" => "[email protected]",
     28      "exp" => TimeProvider::getCurrentTime() + 3600
     29    );
     30    $jwt = JWT::encode($jwt_data, "s3cre7", 'HS256');
     31    $this->assertEquals(
     32      array(
     33        "app_id" => "abcdef",
     34        "intercom_user_jwt" => $jwt
     35      ),
     36      $calculator->messengerSecurityComponent()
     37    );
     38  }
     39
     40  public function testUserIdEmailJWT()
     41  {
     42    $data = array("app_id" => "abcdef", "user_id" => "abcdef", "email" => "[email protected]");
     43    $calculator = new MessengerSecurityCalculator($data, "s3cre7");
     44    $jwt_data = array(
     45      "user_id" => "abcdef",
     46      "email" => "[email protected]",
     47      "exp" => TimeProvider::getCurrentTime() + 3600
     48    );
     49    $jwt = JWT::encode($jwt_data, "s3cre7", 'HS256');
     50    $this->assertEquals(
     51      array(
     52        "app_id" => "abcdef",
     53        "intercom_user_jwt" => $jwt
     54      ),
     55      $calculator->messengerSecurityComponent()
     56    );
     57  }
     58
     59  public function testUserIdEmailNameJWT()
     60  {
     61    $data = array("app_id" => "abcdef", "user_id" => "abcdef", "email" => "[email protected]", "name" => "John Doe");
     62    $calculator = new MessengerSecurityCalculator($data, "s3cre7");
     63    $jwt_data = array(
     64      "user_id" => "abcdef",
     65      "email" => "[email protected]",
     66      "name" => "John Doe",
     67      "exp" => TimeProvider::getCurrentTime() + 3600
     68    );
     69    $jwt = JWT::encode($jwt_data, "s3cre7", 'HS256');
     70    $this->assertEquals(
     71      array(
     72        "app_id" => "abcdef",
     73        "intercom_user_jwt" => $jwt
     74      ),
     75      $calculator->messengerSecurityComponent()
     76    );
    1677  }
    1778
    1879  public function testEmpty()
    1980  {
    20     $data = array();
    21     $calculator = new IdentityVerificationCalculator($data, "s3cre7");
    22     $this->assertEquals(array(), $calculator->identityVerificationComponent());
     81    $data = array("app_id" => "abcdef");
     82    $calculator = new MessengerSecurityCalculator($data, "s3cre7");
     83    $this->assertEquals(
     84      array(
     85        "app_id" => "abcdef",
     86      ),
     87      $calculator->messengerSecurityComponent()
     88    );
     89  }
     90
     91  public function testExtraJWTData()
     92  {
     93    putenv('INTERCOM_PLUGIN_TEST_JWT_DATA=' . json_encode(array("custom_data" => "custom_value")));
     94
     95    $data = array("app_id" => "abcdef", "user_id" => "abcdef", "email" => "[email protected]", "name" => "John Doe");
     96    $calculator = new MessengerSecurityCalculator($data, "s3cre7");
     97    $jwt_data = array(
     98      "user_id" => "abcdef",
     99      "email" => "[email protected]",
     100      "name" => "John Doe",
     101      "custom_data" => "custom_value",
     102      "exp" => TimeProvider::getCurrentTime() + 3600
     103    );
     104    $jwt = JWT::encode($jwt_data, "s3cre7", 'HS256');
     105    $this->assertEquals(
     106      array(
     107        "app_id" => "abcdef",
     108        "intercom_user_jwt" => $jwt
     109      ),
     110      $calculator->messengerSecurityComponent()
     111    );
     112    putenv('INTERCOM_PLUGIN_TEST_JWT_DATA=');
    23113  }
    24114}
  • intercom/trunk/test/SnippetSettingsTest.php

    r3036264 r3272615  
    55}
    66
    7 class IntercomSnippetSettingsTest extends PHPUnit_Framework_TestCase
     7use PHPUnit\Framework\TestCase;
     8use PHPUnit\Framework\MockObject\MockObject;
     9use Firebase\JWT\JWT;
     10
     11class IntercomSnippetSettingsTest extends TestCase
    812{
     13  protected function setUp(): void
     14  {
     15    parent::setUp();
     16    // Freeze time to a specific timestamp
     17    TimeProvider::setMockTime(strtotime('2024-04-08 12:00:00'));
     18  }
     19
     20  protected function tearDown(): void
     21  {
     22    TimeProvider::resetMockTime();
     23    parent::tearDown();
     24  }
     25
    926  public function testJSONRendering()
    1027  {
     
    1431  public function testJSONRenderingWithIdentityVerification()
    1532  {
    16     $snippet_settings = new IntercomSnippetSettings(array("app_id" => "bar"), "foo", new FakeWordPressUserForSnippetTest());
    17     $this->assertEquals("{\"app_id\":\"bar\",\"email\":\"[email protected]\",\"user_hash\":\"a95b0a1ab461c0721d91fbe32a5f5f2a27ac0bfa4bfbcfced168173fa80d4e14\",\"installation_type\":\"wordpress\"}", $snippet_settings->json());
     33    $snippet_settings = new IntercomSnippetSettings(array("app_id" => "bar"), "s3cre7", new FakeWordPressUserForSnippetTest());
     34    $jwt_data = array(
     35      "user_id" => "[email protected]",
     36      "email" => "[email protected]",
     37      "exp" => TimeProvider::getCurrentTime() + 3600
     38    );
     39    $jwt = JWT::encode($jwt_data, "s3cre7", 'HS256');
     40    $this->assertEquals('{"app_id":"bar","intercom_user_jwt":"'.$jwt.'","installation_type":"wordpress"}', $snippet_settings->json());
    1841  }
    1942  public function testJSONRenderingWithIdentityVerificationAndNoSecret()
     
    4063  }
    4164
    42   /**
    43   * @expectedException Exception
    44   */
    4565  public function testValidation()
    4666  {
     67    $this->expectException(\Exception::class);
    4768    $snippet = new IntercomSnippetSettings(array("foo" => "bar"));
    4869  }
  • intercom/trunk/test/SnippetTest.php

    r3036264 r3272615  
    11<?php
    2 class IntercomSnippetTest extends PHPUnit_Framework_TestCase
     2use PHPUnit\Framework\TestCase;
     3
     4class IntercomSnippetTest extends TestCase
    35{
    46  public function testGeneratedHtml()
  • intercom/trunk/test/UserTest.php

    r1622875 r3272615  
    99}
    1010
    11 class UserTest extends PHPUnit_Framework_TestCase
     11use PHPUnit\Framework\TestCase;
     12
     13class UserTest extends TestCase
    1214{
    1315  public function testEmail()
  • intercom/trunk/test/ValidatorTest.php

    r1622875 r3272615  
    11<?php
    2 class ValidatorTest extends PHPUnit_Framework_TestCase
     2use PHPUnit\Framework\TestCase;
     3
     4class ValidatorTest extends TestCase
    35{
    46  public function testValidator()
Note: See TracChangeset for help on using the changeset viewer.