Changeset 3272615
- Timestamp:
- 04/14/2025 03:43:49 PM (10 months ago)
- Location:
- intercom
- Files:
-
- 66 added
- 20 edited
- 1 copied
-
tags/3.0.0 (copied) (copied from intercom/trunk)
-
tags/3.0.0/bootstrap.php (modified) (7 diffs)
-
tags/3.0.0/composer-setup.php (added)
-
tags/3.0.0/composer.json (added)
-
tags/3.0.0/composer.lock (added)
-
tags/3.0.0/readme.md (modified) (4 diffs)
-
tags/3.0.0/readme.txt (modified) (2 diffs)
-
tags/3.0.0/screenshots/settings_auth.png (added)
-
tags/3.0.0/screenshots/settings_not_auth.png (added)
-
tags/3.0.0/screenshots/widget.png (modified) (previous)
-
tags/3.0.0/test/IntercomSettingsPageTest.php (modified) (1 diff)
-
tags/3.0.0/test/SecureModeCalculatorTest.php (modified) (1 diff)
-
tags/3.0.0/test/SnippetSettingsTest.php (modified) (3 diffs)
-
tags/3.0.0/test/SnippetTest.php (modified) (1 diff)
-
tags/3.0.0/test/UserTest.php (modified) (1 diff)
-
tags/3.0.0/test/ValidatorTest.php (modified) (1 diff)
-
tags/3.0.0/vendor (added)
-
tags/3.0.0/vendor/autoload.php (added)
-
tags/3.0.0/vendor/composer (added)
-
tags/3.0.0/vendor/composer/ClassLoader.php (added)
-
tags/3.0.0/vendor/composer/InstalledVersions.php (added)
-
tags/3.0.0/vendor/composer/LICENSE (added)
-
tags/3.0.0/vendor/composer/autoload_classmap.php (added)
-
tags/3.0.0/vendor/composer/autoload_namespaces.php (added)
-
tags/3.0.0/vendor/composer/autoload_psr4.php (added)
-
tags/3.0.0/vendor/composer/autoload_real.php (added)
-
tags/3.0.0/vendor/composer/autoload_static.php (added)
-
tags/3.0.0/vendor/composer/installed.json (added)
-
tags/3.0.0/vendor/composer/installed.php (added)
-
tags/3.0.0/vendor/composer/platform_check.php (added)
-
tags/3.0.0/vendor/firebase (added)
-
tags/3.0.0/vendor/firebase/php-jwt (added)
-
tags/3.0.0/vendor/firebase/php-jwt/CHANGELOG.md (added)
-
tags/3.0.0/vendor/firebase/php-jwt/LICENSE (added)
-
tags/3.0.0/vendor/firebase/php-jwt/README.md (added)
-
tags/3.0.0/vendor/firebase/php-jwt/composer.json (added)
-
tags/3.0.0/vendor/firebase/php-jwt/src (added)
-
tags/3.0.0/vendor/firebase/php-jwt/src/BeforeValidException.php (added)
-
tags/3.0.0/vendor/firebase/php-jwt/src/CachedKeySet.php (added)
-
tags/3.0.0/vendor/firebase/php-jwt/src/ExpiredException.php (added)
-
tags/3.0.0/vendor/firebase/php-jwt/src/JWK.php (added)
-
tags/3.0.0/vendor/firebase/php-jwt/src/JWT.php (added)
-
tags/3.0.0/vendor/firebase/php-jwt/src/Key.php (added)
-
tags/3.0.0/vendor/firebase/php-jwt/src/SignatureInvalidException.php (added)
-
trunk/bootstrap.php (modified) (7 diffs)
-
trunk/composer-setup.php (added)
-
trunk/composer.json (added)
-
trunk/composer.lock (added)
-
trunk/readme.md (modified) (4 diffs)
-
trunk/readme.txt (modified) (2 diffs)
-
trunk/screenshots/settings_auth.png (added)
-
trunk/screenshots/settings_not_auth.png (added)
-
trunk/screenshots/widget.png (modified) (previous)
-
trunk/test/IntercomSettingsPageTest.php (modified) (1 diff)
-
trunk/test/SecureModeCalculatorTest.php (modified) (1 diff)
-
trunk/test/SnippetSettingsTest.php (modified) (3 diffs)
-
trunk/test/SnippetTest.php (modified) (1 diff)
-
trunk/test/UserTest.php (modified) (1 diff)
-
trunk/test/ValidatorTest.php (modified) (1 diff)
-
trunk/vendor (added)
-
trunk/vendor/autoload.php (added)
-
trunk/vendor/composer (added)
-
trunk/vendor/composer/ClassLoader.php (added)
-
trunk/vendor/composer/InstalledVersions.php (added)
-
trunk/vendor/composer/LICENSE (added)
-
trunk/vendor/composer/autoload_classmap.php (added)
-
trunk/vendor/composer/autoload_namespaces.php (added)
-
trunk/vendor/composer/autoload_psr4.php (added)
-
trunk/vendor/composer/autoload_real.php (added)
-
trunk/vendor/composer/autoload_static.php (added)
-
trunk/vendor/composer/installed.json (added)
-
trunk/vendor/composer/installed.php (added)
-
trunk/vendor/composer/platform_check.php (added)
-
trunk/vendor/firebase (added)
-
trunk/vendor/firebase/php-jwt (added)
-
trunk/vendor/firebase/php-jwt/CHANGELOG.md (added)
-
trunk/vendor/firebase/php-jwt/LICENSE (added)
-
trunk/vendor/firebase/php-jwt/README.md (added)
-
trunk/vendor/firebase/php-jwt/composer.json (added)
-
trunk/vendor/firebase/php-jwt/src (added)
-
trunk/vendor/firebase/php-jwt/src/BeforeValidException.php (added)
-
trunk/vendor/firebase/php-jwt/src/CachedKeySet.php (added)
-
trunk/vendor/firebase/php-jwt/src/ExpiredException.php (added)
-
trunk/vendor/firebase/php-jwt/src/JWK.php (added)
-
trunk/vendor/firebase/php-jwt/src/JWT.php (added)
-
trunk/vendor/firebase/php-jwt/src/Key.php (added)
-
trunk/vendor/firebase/php-jwt/src/SignatureInvalidException.php (added)
Legend:
- Unmodified
- Added
- Removed
-
intercom/tags/3.0.0/bootstrap.php
r3036274 r3272615 6 6 Author: Intercom 7 7 Author URI: https://www.intercom.io 8 Version: 2.6.68 Version: 3.0.0 9 9 */ 10 10 11 class IdentityVerificationCalculator 11 require_once __DIR__ . '/vendor/autoload.php'; 12 use Firebase\JWT\JWT; 13 14 class 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 34 class MessengerSecurityCalculator 12 35 { 13 36 private $raw_data = array(); … … 20 43 } 21 44 22 public function identityVerificationComponent()45 public function messengerSecurityComponent() 23 46 { 24 47 $secret_key = $this->getSecretKey(); 48 25 49 if (empty($secret_key)) 26 50 { 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() 46 62 { 47 63 $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; 49 91 } 50 92 … … 53 95 return $this->secret_key; 54 96 } 97 55 98 private function getRawData() 56 99 { … … 195 238 </p> 196 239 <br/> 197 <div style="font-size:0.8em">If the Intercom application associated with your Word press 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> 198 241 </div> 199 242 </div> … … 358 401 { 359 402 $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)); 364 406 $result['installation_type'] = 'wordpress'; 365 407 return $result; … … 386 428 387 429 if (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 389 443 return $value; 390 444 } … … 436 490 { 437 491 $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); 438 496 } 439 497 if (!empty($this->wordpress_user->display_name)) -
intercom/tags/3.0.0/readme.md
r1759316 r3272615 5 5 # Compatibility 6 6 7 Requires PHP 5.6or higher.7 Requires PHP 7.2 or higher. 8 8 9 9 # Local Testing … … 14 14 INTERCOM_PLUGIN_TEST=1 phpunit 15 15 ``` 16 17 # Test the new version of the plugin with Intercom's Wordpress signup flow18 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.20 16 21 17 # Usage … … 31 27 NB: 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. 32 28 33 # Pass extra parameters to the Intercom Messenger29 # Pass custom data attributes to the Intercom Messenger 34 30 35 Using the [ Wordpress Hooks API](https://codex.wordpress.org/Plugin_API) `add_filter` method in your Wordpress theme you can pass extra parametersto the Intercom Messenger (see example below):31 Using 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): 36 32 37 33 ```php 38 add_filter( 'intercom_settings', function( $settings ) { 39 $settings[' user_id'] = $user_id;40 return $settings; 34 add_filter( 'intercom_settings', function( $settings ) { 35 $settings['customer_type'] = $customer_type; 36 return $settings; 41 37 } ); 42 38 ``` … … 45 41 # Users 46 42 47 If a `$current_user` is present, we use their email a s an identifier in the widget.43 If a `$current_user` is present, we use their email and ID as an identifier in the widget. 48 44 We 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. 49 45 -
intercom/tags/3.0.0/readme.txt
r3036264 r3272615 1 === Plugin Name === 2 Contributors: bobintercom 1 === Intercom === 2 Contributors: bobintercom, jacopointercom 3 Tags: intercom, ai, customer, chat 4 Requires at least: 4.7.0 5 Tested up to: 6.7.2 6 Requires PHP: 7.2 3 7 License: Apache 2.0 4 Tags: intercom, customer, chat 5 Requires at least: 4.2.0 6 Tested up to: 6.4.3 8 Stable tag: 3.0 7 9 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. 10 Official Intercom WordPress plugin: Engage visitors in real time, power growth with AI, and convert leads into loyal customers. 11 11 12 12 == Description == 13 13 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. 15 15 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. 16 By 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. 19 17 20 18 == Installation == … … 22 20 Installing Intercom on your WordPress site takes just a few minutes. 23 21 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).22 You 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). 25 23 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. 24 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). 25 26 The 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. 27 27 28 28 Note: 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 == 31 1. Plugin settings authenticate with Intercom settings_not_auth.png 32 2. Plugin settings successfully authenticated with Intercom settings_auth.png 33 3. 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 = 44 Upgrade 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 1 1 <?php 2 class IntercomSettingsPageTest extends PHPUnit_Framework_TestCase 2 use PHPUnit\Framework\TestCase; 3 use PHPUnit\Framework\MockObject\MockObject; 4 5 class IntercomSettingsPageTest extends TestCase 3 6 { 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); 6 236 } 7 237 } -
intercom/tags/3.0.0/test/SecureModeCalculatorTest.php
r3036264 r3272615 1 1 <?php 2 class IdentityVerificationCalculatorTest extends PHPUnit_Framework_TestCase 2 3 use PHPUnit\Framework\TestCase; 4 use Firebase\JWT\JWT; 5 6 class MessengerSecurityCalculatorTest extends TestCase 3 7 { 4 p ublic function testHashEmail()8 protected function setUp(): void 5 9 { 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')); 9 13 } 10 14 11 p ublic function testHashUserId()15 protected function tearDown(): void 12 16 { 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 ); 16 77 } 17 78 18 79 public function testEmpty() 19 80 { 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='); 23 113 } 24 114 } -
intercom/tags/3.0.0/test/SnippetSettingsTest.php
r3036264 r3272615 5 5 } 6 6 7 class IntercomSnippetSettingsTest extends PHPUnit_Framework_TestCase 7 use PHPUnit\Framework\TestCase; 8 use PHPUnit\Framework\MockObject\MockObject; 9 use Firebase\JWT\JWT; 10 11 class IntercomSnippetSettingsTest extends TestCase 8 12 { 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 9 26 public function testJSONRendering() 10 27 { … … 14 31 public function testJSONRenderingWithIdentityVerification() 15 32 { 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()); 18 41 } 19 42 public function testJSONRenderingWithIdentityVerificationAndNoSecret() … … 40 63 } 41 64 42 /**43 * @expectedException Exception44 */45 65 public function testValidation() 46 66 { 67 $this->expectException(\Exception::class); 47 68 $snippet = new IntercomSnippetSettings(array("foo" => "bar")); 48 69 } -
intercom/tags/3.0.0/test/SnippetTest.php
r3036264 r3272615 1 1 <?php 2 class IntercomSnippetTest extends PHPUnit_Framework_TestCase 2 use PHPUnit\Framework\TestCase; 3 4 class IntercomSnippetTest extends TestCase 3 5 { 4 6 public function testGeneratedHtml() -
intercom/tags/3.0.0/test/UserTest.php
r1622875 r3272615 9 9 } 10 10 11 class UserTest extends PHPUnit_Framework_TestCase 11 use PHPUnit\Framework\TestCase; 12 13 class UserTest extends TestCase 12 14 { 13 15 public function testEmail() -
intercom/tags/3.0.0/test/ValidatorTest.php
r1622875 r3272615 1 1 <?php 2 class ValidatorTest extends PHPUnit_Framework_TestCase 2 use PHPUnit\Framework\TestCase; 3 4 class ValidatorTest extends TestCase 3 5 { 4 6 public function testValidator() -
intercom/trunk/bootstrap.php
r3036274 r3272615 6 6 Author: Intercom 7 7 Author URI: https://www.intercom.io 8 Version: 2.6.68 Version: 3.0.0 9 9 */ 10 10 11 class IdentityVerificationCalculator 11 require_once __DIR__ . '/vendor/autoload.php'; 12 use Firebase\JWT\JWT; 13 14 class 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 34 class MessengerSecurityCalculator 12 35 { 13 36 private $raw_data = array(); … … 20 43 } 21 44 22 public function identityVerificationComponent()45 public function messengerSecurityComponent() 23 46 { 24 47 $secret_key = $this->getSecretKey(); 48 25 49 if (empty($secret_key)) 26 50 { 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() 46 62 { 47 63 $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; 49 91 } 50 92 … … 53 95 return $this->secret_key; 54 96 } 97 55 98 private function getRawData() 56 99 { … … 195 238 </p> 196 239 <br/> 197 <div style="font-size:0.8em">If the Intercom application associated with your Word press 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> 198 241 </div> 199 242 </div> … … 358 401 { 359 402 $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)); 364 406 $result['installation_type'] = 'wordpress'; 365 407 return $result; … … 386 428 387 429 if (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 389 443 return $value; 390 444 } … … 436 490 { 437 491 $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); 438 496 } 439 497 if (!empty($this->wordpress_user->display_name)) -
intercom/trunk/readme.md
r1759316 r3272615 5 5 # Compatibility 6 6 7 Requires PHP 5.6or higher.7 Requires PHP 7.2 or higher. 8 8 9 9 # Local Testing … … 14 14 INTERCOM_PLUGIN_TEST=1 phpunit 15 15 ``` 16 17 # Test the new version of the plugin with Intercom's Wordpress signup flow18 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.20 16 21 17 # Usage … … 31 27 NB: 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. 32 28 33 # Pass extra parameters to the Intercom Messenger29 # Pass custom data attributes to the Intercom Messenger 34 30 35 Using the [ Wordpress Hooks API](https://codex.wordpress.org/Plugin_API) `add_filter` method in your Wordpress theme you can pass extra parametersto the Intercom Messenger (see example below):31 Using 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): 36 32 37 33 ```php 38 add_filter( 'intercom_settings', function( $settings ) { 39 $settings[' user_id'] = $user_id;40 return $settings; 34 add_filter( 'intercom_settings', function( $settings ) { 35 $settings['customer_type'] = $customer_type; 36 return $settings; 41 37 } ); 42 38 ``` … … 45 41 # Users 46 42 47 If a `$current_user` is present, we use their email a s an identifier in the widget.43 If a `$current_user` is present, we use their email and ID as an identifier in the widget. 48 44 We 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. 49 45 -
intercom/trunk/readme.txt
r3036264 r3272615 1 === Plugin Name === 2 Contributors: bobintercom 1 === Intercom === 2 Contributors: bobintercom, jacopointercom 3 Tags: intercom, ai, customer, chat 4 Requires at least: 4.7.0 5 Tested up to: 6.7.2 6 Requires PHP: 7.2 3 7 License: Apache 2.0 4 Tags: intercom, customer, chat 5 Requires at least: 4.2.0 6 Tested up to: 6.4.3 8 Stable tag: 3.0 7 9 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. 10 Official Intercom WordPress plugin: Engage visitors in real time, power growth with AI, and convert leads into loyal customers. 11 11 12 12 == Description == 13 13 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. 15 15 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. 16 By 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. 19 17 20 18 == Installation == … … 22 20 Installing Intercom on your WordPress site takes just a few minutes. 23 21 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).22 You 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). 25 23 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. 24 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). 25 26 The 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. 27 27 28 28 Note: 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 == 31 1. Plugin settings authenticate with Intercom settings_not_auth.png 32 2. Plugin settings successfully authenticated with Intercom settings_auth.png 33 3. 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 = 44 Upgrade 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 1 1 <?php 2 class IntercomSettingsPageTest extends PHPUnit_Framework_TestCase 2 use PHPUnit\Framework\TestCase; 3 use PHPUnit\Framework\MockObject\MockObject; 4 5 class IntercomSettingsPageTest extends TestCase 3 6 { 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); 6 236 } 7 237 } -
intercom/trunk/test/SecureModeCalculatorTest.php
r3036264 r3272615 1 1 <?php 2 class IdentityVerificationCalculatorTest extends PHPUnit_Framework_TestCase 2 3 use PHPUnit\Framework\TestCase; 4 use Firebase\JWT\JWT; 5 6 class MessengerSecurityCalculatorTest extends TestCase 3 7 { 4 p ublic function testHashEmail()8 protected function setUp(): void 5 9 { 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')); 9 13 } 10 14 11 p ublic function testHashUserId()15 protected function tearDown(): void 12 16 { 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 ); 16 77 } 17 78 18 79 public function testEmpty() 19 80 { 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='); 23 113 } 24 114 } -
intercom/trunk/test/SnippetSettingsTest.php
r3036264 r3272615 5 5 } 6 6 7 class IntercomSnippetSettingsTest extends PHPUnit_Framework_TestCase 7 use PHPUnit\Framework\TestCase; 8 use PHPUnit\Framework\MockObject\MockObject; 9 use Firebase\JWT\JWT; 10 11 class IntercomSnippetSettingsTest extends TestCase 8 12 { 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 9 26 public function testJSONRendering() 10 27 { … … 14 31 public function testJSONRenderingWithIdentityVerification() 15 32 { 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()); 18 41 } 19 42 public function testJSONRenderingWithIdentityVerificationAndNoSecret() … … 40 63 } 41 64 42 /**43 * @expectedException Exception44 */45 65 public function testValidation() 46 66 { 67 $this->expectException(\Exception::class); 47 68 $snippet = new IntercomSnippetSettings(array("foo" => "bar")); 48 69 } -
intercom/trunk/test/SnippetTest.php
r3036264 r3272615 1 1 <?php 2 class IntercomSnippetTest extends PHPUnit_Framework_TestCase 2 use PHPUnit\Framework\TestCase; 3 4 class IntercomSnippetTest extends TestCase 3 5 { 4 6 public function testGeneratedHtml() -
intercom/trunk/test/UserTest.php
r1622875 r3272615 9 9 } 10 10 11 class UserTest extends PHPUnit_Framework_TestCase 11 use PHPUnit\Framework\TestCase; 12 13 class UserTest extends TestCase 12 14 { 13 15 public function testEmail() -
intercom/trunk/test/ValidatorTest.php
r1622875 r3272615 1 1 <?php 2 class ValidatorTest extends PHPUnit_Framework_TestCase 2 use PHPUnit\Framework\TestCase; 3 4 class ValidatorTest extends TestCase 3 5 { 4 6 public function testValidator()
Note: See TracChangeset
for help on using the changeset viewer.