Skip to content

Commit cb70c1b

Browse files
eredi93Copilot
andauthored
Introduce JWT and PHP upgrade (#127)
* upgrade php to support newer version of wp and introduce jwt * allow adding sensitive cdas to to JWT * Update readme.txt Co-authored-by: Copilot <[email protected]> * remove test cache and update gitignore --------- Co-authored-by: Copilot <[email protected]>
1 parent af6e88f commit cb70c1b

38 files changed

+5389
-68
lines changed

.circleci/config.yml

+4-4
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,21 @@ version: 2.1
33
jobs:
44
build-and-test:
55
docker:
6-
- image: cimg/php:5.6
6+
- image: cimg/php:7.2
77
steps:
88
- checkout
99
- run:
1010
name: Install PHPUnit
1111
command: |
12-
wget https://phar.phpunit.de/phpunit-4.8.9.phar
12+
wget https://phar.phpunit.de/phpunit-8.5.33.phar
1313
- run:
1414
name: Make PHPUnit executable
1515
command: |
16-
chmod +x ./phpunit-4.8.9.phar
16+
chmod +x ./phpunit-8.5.33.phar
1717
- run:
1818
name: Run PHPUnit
1919
command: |
20-
INTERCOM_PLUGIN_TEST=1 php ./phpunit-4.8.9.phar
20+
INTERCOM_PLUGIN_TEST=1 php ./phpunit-8.5.33.phar
2121
2222
workflows:
2323
sample:

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
*.swo
22
*.swp
33
intercom-wordpress.zip
4+
.gitignore

bootstrap.php

+80-22
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,33 @@
55
Description: Official <a href="https://www.intercom.io">Intercom</a> support for WordPress.
66
Author: Intercom
77
Author URI: https://www.intercom.io
8-
Version: 2.6.6
8+
Version: 3.0.0
99
*/
1010

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
1235
{
1336
private $raw_data = array();
1437
private $secret_key = "";
@@ -19,39 +42,59 @@ public function __construct($data, $secret_key)
1942
$this->secret_key = $secret_key;
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");
51+
return $this->getRawData();
3252
}
33-
if (array_key_exists("email", $this->getRawData()))
53+
if (array_key_exists("user_id", $this->getRawData()) || array_key_exists("email", $this->getRawData()))
3454
{
35-
return $this->identityVerificationHashComponent("email");
55+
return $this->messengerSecurityJWTComponent();
3656
}
37-
return $this->emptyIdentityVerificationHashComponent();
38-
}
3957

40-
private function emptyIdentityVerificationHashComponent()
41-
{
42-
return array();
58+
return $this->getRawData();
4359
}
4460

45-
private function identityVerificationHashComponent($key)
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

5193
private function getSecretKey()
5294
{
5395
return $this->secret_key;
5496
}
97+
5598
private function getRawData()
5699
{
57100
return $this->raw_data;
@@ -357,10 +400,9 @@ public function appId()
357400
private function getRawData()
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;
366408
}
@@ -385,7 +427,19 @@ private function validateRawData($raw_data)
385427
}
386428

387429
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+
389443
return $value;
390444
}
391445
}
@@ -436,6 +490,10 @@ public function buildSettings()
436490
{
437491
$this->settings["email"] = WordPressEscaper::escJS($this->wordpress_user->user_email);
438492
}
493+
if (!empty($this->wordpress_user->ID))
494+
{
495+
$this->settings["user_id"] = WordPressEscaper::escJS($this->wordpress_user->ID);
496+
}
439497
if (!empty($this->wordpress_user->display_name))
440498
{
441499
$this->settings["name"] = WordPressEscaper::escJS($this->wordpress_user->display_name);

0 commit comments

Comments
 (0)