Tawk.To Live Chat - Version 0.6.0

Version Description

  • Security Update Add CSRF tokens and specific action access checks.
  • Security Update Use application/json content type for ajax requests.
Download this release

Release Info

Developer alvinsotawk
Plugin Icon 128x128 Tawk.To Live Chat
Version 0.6.0
Comparing to
See all releases

Code changes from version 0.5.4 to 0.6.0

assets/{tawk.admin.css → css/tawk.admin.css} RENAMED
File without changes
assets/{tawk.admin.js → js/tawk.admin.js} RENAMED
@@ -1,28 +1,26 @@
1
  jQuery(function() {
2
  document.getElementById("defaultOpen").click();
3
 
4
- console.log(jQuery("#always_display").prop("checked"));
5
- if(jQuery("#always_display").prop("checked")){
6
  jQuery('.twk_selected_display').hide();
7
  jQuery('#show_onfrontpage').prop('disabled', true);
8
  jQuery('#show_oncategory').prop('disabled', true);
9
  jQuery('#show_ontagpage').prop('disabled', true);
10
  jQuery('#show_onarticlepages').prop('disabled', true);
11
  jQuery('#include_url').prop('disabled', true);
12
- }else{
13
  jQuery('.twk_selected_display').show();
14
-
15
  }
16
 
17
  jQuery("#always_display").change(function() {
18
- if(this.checked){
19
  jQuery('.twk_selected_display').fadeOut();
20
  jQuery('#show_onfrontpage').prop('disabled', true);
21
  jQuery('#show_oncategory').prop('disabled', true);
22
  jQuery('#show_ontagpage').prop('disabled', true);
23
  jQuery('#show_onarticlepages').prop('disabled', true);
24
  jQuery('#include_url').prop('disabled', true);
25
- }else{
26
  jQuery('.twk_selected_display').fadeIn();
27
  jQuery('#show_onfrontpage').prop('disabled', false);
28
  jQuery('#show_oncategory').prop('disabled', false);
@@ -32,31 +30,29 @@ jQuery(function() {
32
  }
33
  });
34
 
35
-
36
  jQuery("#exclude_url").change(function() {
37
- if(this.checked){
38
  jQuery("#exlucded_urls_container").fadeIn();
39
- }else{
40
  jQuery("#exlucded_urls_container").fadeOut();
41
  }
42
  });
43
 
44
- if(jQuery("#include_url").prop("checked")){
45
  jQuery("#included_urls_container").show();
46
  }
47
 
48
  jQuery("#include_url").change(function() {
49
- if(this.checked){
50
  jQuery("#included_urls_container").fadeIn();
51
- }else{
52
  jQuery("#included_urls_container").fadeOut();
53
  }
54
  });
55
 
56
- if(jQuery("#exclude_url").prop("checked")){
57
  jQuery("#exlucded_urls_container").fadeIn();
58
  }
59
-
60
  });
61
 
62
 
1
  jQuery(function() {
2
  document.getElementById("defaultOpen").click();
3
 
4
+ if (jQuery("#always_display").prop("checked")) {
 
5
  jQuery('.twk_selected_display').hide();
6
  jQuery('#show_onfrontpage').prop('disabled', true);
7
  jQuery('#show_oncategory').prop('disabled', true);
8
  jQuery('#show_ontagpage').prop('disabled', true);
9
  jQuery('#show_onarticlepages').prop('disabled', true);
10
  jQuery('#include_url').prop('disabled', true);
11
+ } else {
12
  jQuery('.twk_selected_display').show();
 
13
  }
14
 
15
  jQuery("#always_display").change(function() {
16
+ if (this.checked) {
17
  jQuery('.twk_selected_display').fadeOut();
18
  jQuery('#show_onfrontpage').prop('disabled', true);
19
  jQuery('#show_oncategory').prop('disabled', true);
20
  jQuery('#show_ontagpage').prop('disabled', true);
21
  jQuery('#show_onarticlepages').prop('disabled', true);
22
  jQuery('#include_url').prop('disabled', true);
23
+ } else {
24
  jQuery('.twk_selected_display').fadeIn();
25
  jQuery('#show_onfrontpage').prop('disabled', false);
26
  jQuery('#show_oncategory').prop('disabled', false);
30
  }
31
  });
32
 
 
33
  jQuery("#exclude_url").change(function() {
34
+ if (this.checked) {
35
  jQuery("#exlucded_urls_container").fadeIn();
36
+ } else {
37
  jQuery("#exlucded_urls_container").fadeOut();
38
  }
39
  });
40
 
41
+ if (jQuery("#include_url").prop("checked")) {
42
  jQuery("#included_urls_container").show();
43
  }
44
 
45
  jQuery("#include_url").change(function() {
46
+ if (this.checked) {
47
  jQuery("#included_urls_container").fadeIn();
48
+ } else {
49
  jQuery("#included_urls_container").fadeOut();
50
  }
51
  });
52
 
53
+ if (jQuery("#exclude_url").prop("checked")) {
54
  jQuery("#exlucded_urls_container").fadeIn();
55
  }
 
56
  });
57
 
58
 
assets/js/tawk.selection.js ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // variables
2
+ var currentHost = window.location.protocol + '//' + window.location.host;
3
+ var iframeUrl = tawk_selection_data.url.iframe + '&parentDomain=' + currentHost;
4
+ var baseUrl = tawk_selection_data.url.base;
5
+
6
+ jQuery('#tawkIframe').attr('src', iframeUrl);
7
+
8
+ window.addEventListener('message', function (e) {
9
+ if(e.origin === baseUrl) {
10
+
11
+ if(e.data.action === 'setWidget') {
12
+ setWidget(e);
13
+ }
14
+
15
+ if(e.data.action === 'removeWidget') {
16
+ removeWidget(e);
17
+ }
18
+
19
+ if(e.data.action === 'reloadHeight') {
20
+ reloadIframeHeight(e.data.height);
21
+ }
22
+ }
23
+ });
24
+
25
+ function setWidget (e) {
26
+ const data = {
27
+ pageId : e.data.pageId,
28
+ widgetId : e.data.widgetId,
29
+ nonce : tawk_selection_data.nonce.setWidget
30
+ };
31
+
32
+ jQuery.ajax({
33
+ type : 'POST',
34
+ url : ajaxurl + '?action=tawkto_setwidget',
35
+ contentType : 'application/json',
36
+ dataType : 'json',
37
+ data : JSON.stringify(data),
38
+ success : function (r) {
39
+ if (!r.success) {
40
+ return e.source.postMessage({action: 'setFail'}, baseUrl);
41
+ }
42
+ e.source.postMessage({action: 'setDone'}, baseUrl);
43
+ },
44
+ error : function () {
45
+ e.source.postMessage({action: 'setFail'}, baseUrl);
46
+ }
47
+ });
48
+ }
49
+
50
+ function removeWidget (e) {
51
+ const data = {
52
+ nonce : tawk_selection_data.nonce.removeWidget
53
+ }
54
+
55
+ jQuery.ajax({
56
+ type : 'POST',
57
+ url : ajaxurl + '?action=tawkto_removewidget',
58
+ contentType : 'application/json',
59
+ dataType : 'json',
60
+ data : JSON.stringify(data),
61
+ success : function (r) {
62
+ if (!r.success) {
63
+ return e.source.postMessage({action: 'removeFail'}, baseUrl);
64
+ }
65
+ e.source.postMessage({action: 'removeDone'}, baseUrl);
66
+ },
67
+ error : function () {
68
+ e.source.postMessage({action: 'removeFail'}, baseUrl);
69
+ }
70
+ });
71
+ }
72
+
73
+ function reloadIframeHeight(height) {
74
+ if (!height) {
75
+ return;
76
+ }
77
+
78
+ var iframe = jQuery('#tawkIframe');
79
+ if (height === iframe.height()) {
80
+ return;
81
+ }
82
+
83
+ iframe.height(height);
84
+ }
readme.txt CHANGED
@@ -2,8 +2,9 @@
2
  Contributors: tawkto
3
  Tags: tawk,tawk.to,tawkto,chat,free chat,livechat,chat widget,plugin,chat for web,chat online,chat software,free live chat,IM Chat,,live chat,live support,live web chat,online chat,online support,snapengage,wordpress chat,wordpress live chat
4
  Requires at least: 2.7
5
- Tested up to: 5.7
6
- Stable tag: 0.5.4
 
7
 
8
  (OFFICIAL tawk.to plugin) Instantly chat with visitors on your website with the free tawk.to chat widget.
9
  Website: [http://tawk.to](http://tawk.to)
@@ -55,6 +56,13 @@ Note: You will need a free tawk.to account : [Create one for free here!](https:/
55
 
56
  == Changelog ==
57
 
 
 
 
 
 
 
 
58
  = 0.5.4 =
59
  * Added function for widget selection iframe to auto resize.
60
  * Provided platform identifier to widget selection iframe.
2
  Contributors: tawkto
3
  Tags: tawk,tawk.to,tawkto,chat,free chat,livechat,chat widget,plugin,chat for web,chat online,chat software,free live chat,IM Chat,,live chat,live support,live web chat,online chat,online support,snapengage,wordpress chat,wordpress live chat
4
  Requires at least: 2.7
5
+ Requires PHP: 5.6
6
+ Tested up to: 5.8
7
+ Stable tag: 0.6.0
8
 
9
  (OFFICIAL tawk.to plugin) Instantly chat with visitors on your website with the free tawk.to chat widget.
10
  Website: [http://tawk.to](http://tawk.to)
56
 
57
  == Changelog ==
58
 
59
+ = 0.6.0 =
60
+ * **Security Update** Add CSRF tokens and specific action access checks.
61
+ * **Security Update** Use `application/json` content type for ajax requests.
62
+
63
+ = 0.5.5 =
64
+ * Supported version bump 5.8.
65
+
66
  = 0.5.4 =
67
  * Added function for widget selection iframe to auto resize.
68
  * Provided platform identifier to widget selection iframe.
tawkto.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Tawk.to Live Chat
4
  Plugin URI: https://www.tawk.to
5
  Description: Embeds Tawk.to live chat widget to your site
6
- Version: 0.5.4
7
  Author: Tawkto
8
  Text Domain: tawk-to-live-chat
9
  */
@@ -13,6 +13,8 @@ if(!class_exists('TawkTo_Settings')){
13
  const TAWK_WIDGET_ID_VARIABLE = 'tawkto-embed-widget-widget-id';
14
  const TAWK_PAGE_ID_VARIABLE = 'tawkto-embed-widget-page-id';
15
  const TAWK_VISIBILITY_OPTIONS = 'tawkto-visibility-options';
 
 
16
 
17
  public function __construct(){
18
 
@@ -52,10 +54,10 @@ if(!class_exists('TawkTo_Settings')){
52
  if($hook != 'settings_page_tawkto_plugin')
53
  return;
54
 
55
- wp_register_style( 'tawk_admin_style', plugins_url( 'assets/tawk.admin.css' , __FILE__ ) );
56
- wp_enqueue_style( 'tawk_admin_style' );
57
 
58
- wp_enqueue_script( 'tawk_admin_script', plugins_url( 'assets/tawk.admin.js' , __FILE__ ) );
59
 
60
  }
61
 
@@ -66,22 +68,43 @@ if(!class_exists('TawkTo_Settings')){
66
  public function action_setwidget() {
67
  header('Content-Type: application/json');
68
 
69
- if (!isset($_POST['pageId']) || !isset($_POST['widgetId'])) {
70
- echo json_encode(array('success' => FALSE));
71
- die();
72
- }
 
 
 
 
73
 
74
- if (!self::ids_are_correct($_POST['pageId'], $_POST['widgetId'])) {
75
- echo json_encode(array('success' => FALSE));
76
- die();
 
 
 
 
 
 
 
 
 
 
 
 
77
  }
78
 
79
- update_option(self::TAWK_PAGE_ID_VARIABLE, $_POST['pageId']);
80
- update_option(self::TAWK_WIDGET_ID_VARIABLE, $_POST['widgetId']);
 
 
 
81
 
 
 
82
 
83
- echo json_encode(array('success' => TRUE));
84
- die();
85
  }
86
 
87
  function tawk_admin_notice() {
@@ -99,11 +122,47 @@ if(!class_exists('TawkTo_Settings')){
99
  public function action_removewidget() {
100
  header('Content-Type: application/json');
101
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  update_option(self::TAWK_PAGE_ID_VARIABLE, '');
103
  update_option(self::TAWK_WIDGET_ID_VARIABLE, '');
104
 
105
- echo json_encode(array('success' => TRUE));
106
- die();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  }
108
 
109
  public function validate_options($input){
@@ -167,6 +226,8 @@ if(!class_exists('TawkTo_Settings')){
167
  .'&currentPageId='.$page_id
168
  .'&transparentBackground=1'
169
  .'&pltf=wordpress';
 
 
170
 
171
 
172
  include(sprintf("%s/templates/settings.php", dirname(__FILE__)));
3
  Plugin Name: Tawk.to Live Chat
4
  Plugin URI: https://www.tawk.to
5
  Description: Embeds Tawk.to live chat widget to your site
6
+ Version: 0.6.0
7
  Author: Tawkto
8
  Text Domain: tawk-to-live-chat
9
  */
13
  const TAWK_WIDGET_ID_VARIABLE = 'tawkto-embed-widget-widget-id';
14
  const TAWK_PAGE_ID_VARIABLE = 'tawkto-embed-widget-page-id';
15
  const TAWK_VISIBILITY_OPTIONS = 'tawkto-visibility-options';
16
+ const TAWK_ACTION_SET_WIDGET = 'tawkto-set-widget';
17
+ const TAWK_ACTION_REMOVE_WIDGET = 'tawkto-remove-widget';
18
 
19
  public function __construct(){
20
 
54
  if($hook != 'settings_page_tawkto_plugin')
55
  return;
56
 
57
+ wp_register_style( 'tawk_admin_style', plugins_url( 'assets/css/tawk.admin.css' , __FILE__ ) );
58
+ wp_enqueue_style( 'tawk_admin_style' );
59
 
60
+ wp_enqueue_script( 'tawk_admin_script', plugins_url( 'assets/js/tawk.admin.js' , __FILE__ ) );
61
 
62
  }
63
 
68
  public function action_setwidget() {
69
  header('Content-Type: application/json');
70
 
71
+ if (wp_is_json_request() === false) {
72
+ $response['success'] = false;
73
+ $response['message'] = 'Invalid request';
74
+ wp_send_json($response);
75
+ wp_die();
76
+ };
77
+
78
+ $postData = json_decode(file_get_contents('php://input'), true);
79
 
80
+ $response = array(
81
+ 'success' => true
82
+ );
83
+
84
+ if ($this->validate_request_auth($postData, self::TAWK_ACTION_SET_WIDGET) === false) {
85
+ $response['success'] = false;
86
+ $response['message'] = 'Unauthorized';
87
+ wp_send_json($response);
88
+ wp_die();
89
+ };
90
+
91
+ if (!isset($postData['pageId']) || !isset($postData['widgetId'])) {
92
+ $response['success'] = false;
93
+ wp_send_json($response);
94
+ wp_die();
95
  }
96
 
97
+ if (!self::ids_are_correct($postData['pageId'], $postData['widgetId'])) {
98
+ $response['success'] = false;
99
+ wp_send_json($response);
100
+ wp_die();
101
+ }
102
 
103
+ update_option(self::TAWK_PAGE_ID_VARIABLE, $postData['pageId']);
104
+ update_option(self::TAWK_WIDGET_ID_VARIABLE, $postData['widgetId']);
105
 
106
+ wp_send_json($response);
107
+ wp_die();
108
  }
109
 
110
  function tawk_admin_notice() {
122
  public function action_removewidget() {
123
  header('Content-Type: application/json');
124
 
125
+ if (wp_is_json_request() === false) {
126
+ $response['success'] = false;
127
+ $response['message'] = 'Invalid request';
128
+ wp_send_json($response);
129
+ wp_die();
130
+ };
131
+
132
+ $postData = json_decode(file_get_contents('php://input'), true);
133
+
134
+ $response = array(
135
+ 'success' => true
136
+ );
137
+
138
+ if ($this->validate_request_auth($postData, self::TAWK_ACTION_REMOVE_WIDGET) === false) {
139
+ $response['success'] = false;
140
+ $response['message'] = 'Unauthorized';
141
+ wp_send_json($response);
142
+ wp_die();
143
+ };
144
+
145
  update_option(self::TAWK_PAGE_ID_VARIABLE, '');
146
  update_option(self::TAWK_WIDGET_ID_VARIABLE, '');
147
 
148
+ wp_send_json($response);
149
+ wp_die();
150
+ }
151
+
152
+ private function validate_request_auth($postData = array(), $action) {
153
+ if (current_user_can('administrator') === false) {
154
+ return false;
155
+ }
156
+
157
+ if (isset($postData['nonce']) === false) {
158
+ return false;
159
+ }
160
+
161
+ if (wp_verify_nonce($postData['nonce'], $action) === false) {
162
+ return false;
163
+ }
164
+
165
+ return true;
166
  }
167
 
168
  public function validate_options($input){
226
  .'&currentPageId='.$page_id
227
  .'&transparentBackground=1'
228
  .'&pltf=wordpress';
229
+ $set_widget_nonce = wp_create_nonce(self::TAWK_ACTION_SET_WIDGET);
230
+ $remove_widget_nonce = wp_create_nonce(self::TAWK_ACTION_REMOVE_WIDGET);
231
 
232
 
233
  include(sprintf("%s/templates/settings.php", dirname(__FILE__)));
templates/settings.php CHANGED
@@ -52,73 +52,24 @@ if ( ! defined( 'ABSPATH' ) ) {
52
  $display_widgetsettings = true;
53
  }
54
  if ($display_widgetsettings == TRUE){
 
 
 
 
 
 
 
 
 
 
 
 
55
  ?>
56
  <iframe
57
  id="tawkIframe"
58
  src=""
59
  style="min-height: 295px; width : 100%; border: none; margin-top: 20px">
60
  </iframe>
61
- <script>
62
- var currentHost = window.location.protocol + "//" + window.location.host;
63
- var url = "<?php echo $iframe_url ?>&parentDomain=" + currentHost;
64
- jQuery('#tawkIframe').attr('src', url);
65
- var iframe = jQuery('#tawk_widget_customization')[0];
66
-
67
- window.addEventListener('message', function(e) {
68
- if(e.origin === '<?php echo $base_url ?>') {
69
-
70
- if(e.data.action === 'setWidget') {
71
- setWidget(e);
72
- }
73
-
74
- if(e.data.action === 'removeWidget') {
75
- removeWidget(e);
76
- }
77
-
78
- if(e.data.action === 'reloadHeight') {
79
- reloadIframeHeight(e.data.height);
80
- }
81
- }
82
- });
83
-
84
- function setWidget(e) {
85
- jQuery.post(ajaxurl, {
86
- action : 'tawkto_setwidget',
87
- pageId : e.data.pageId,
88
- widgetId : e.data.widgetId
89
- }, function(r) {
90
- if(r.success) {
91
- e.source.postMessage({action: 'setDone'}, '<?php echo $base_url ?>');
92
- } else {
93
- e.source.postMessage({action: 'setFail'}, '<?php echo $base_url ?>');
94
- }
95
-
96
- });
97
- }
98
-
99
- function removeWidget(e) {
100
- jQuery.post(ajaxurl, {action: 'tawkto_removewidget'}, function(r) {
101
- if(r.success) {
102
- e.source.postMessage({action: 'removeDone'}, '<?php echo $base_url ?>');
103
- } else {
104
- e.source.postMessage({action: 'removeFail'}, '<?php echo $base_url ?>');
105
- }
106
- });
107
- }
108
-
109
- function reloadIframeHeight(height) {
110
- if (!height) {
111
- return;
112
- }
113
-
114
- var iframe = jQuery('#tawkIframe');
115
- if (height === iframe.height()) {
116
- return;
117
- }
118
-
119
- iframe.height(height);
120
- }
121
- </script>
122
  <?php
123
  }else{
124
  echo "<h2>Property and widget is already set.</h2>";
@@ -127,6 +78,7 @@ if ( ! defined( 'ABSPATH' ) ) {
127
  }
128
  ?>
129
  </div>
 
130
  <form method="post" action="options.php">
131
  <?php
132
  settings_fields( 'tawk_options' );
52
  $display_widgetsettings = true;
53
  }
54
  if ($display_widgetsettings == TRUE){
55
+
56
+ wp_enqueue_script('tawk-selection', plugin_dir_url(__DIR__).'assets/js/tawk.selection.js');
57
+ wp_localize_script('tawk-selection', 'tawk_selection_data', array(
58
+ 'url' => array(
59
+ 'base' => $base_url,
60
+ 'iframe' => $iframe_url,
61
+ ),
62
+ 'nonce' => array(
63
+ 'setWidget' => $set_widget_nonce,
64
+ 'removeWidget' => $remove_widget_nonce
65
+ )
66
+ ));
67
  ?>
68
  <iframe
69
  id="tawkIframe"
70
  src=""
71
  style="min-height: 295px; width : 100%; border: none; margin-top: 20px">
72
  </iframe>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  <?php
74
  }else{
75
  echo "<h2>Property and widget is already set.</h2>";
78
  }
79
  ?>
80
  </div>
81
+ </div>
82
  <form method="post" action="options.php">
83
  <?php
84
  settings_fields( 'tawk_options' );
templates/widget.php CHANGED
@@ -1,4 +1,4 @@
1
- <!--Start of Tawk.to Script (0.5.4)-->
2
  <script type="text/javascript">
3
  var Tawk_API=Tawk_API||{};
4
  <?php
@@ -8,12 +8,12 @@ if(isset($customer_details) && $enable_visitor_recognition) {
8
  ?>
9
  var Tawk_LoadStart=new Date();
10
  (function(){
11
- var s1=document.createElement("script"),s0=document.getElementsByTagName("script")[0];
12
- s1.async=true;
13
- s1.src='<?php echo esc_url('https://embed.tawk.to/'.$page_id.'/'.$widget_id); ?>';
14
- s1.charset='UTF-8';
15
- s1.setAttribute('crossorigin','*');
16
- s0.parentNode.insertBefore(s1,s0);
17
  })();
18
  </script>
19
- <!--End of Tawk.to Script (0.5.4)-->
1
+ <!--Start of Tawk.to Script (0.6.0)-->
2
  <script type="text/javascript">
3
  var Tawk_API=Tawk_API||{};
4
  <?php
8
  ?>
9
  var Tawk_LoadStart=new Date();
10
  (function(){
11
+ var s1=document.createElement("script"),s0=document.getElementsByTagName("script")[0];
12
+ s1.async=true;
13
+ s1.src='<?php echo esc_url('https://embed.tawk.to/'.$page_id.'/'.$widget_id); ?>';
14
+ s1.charset='UTF-8';
15
+ s1.setAttribute('crossorigin','*');
16
+ s0.parentNode.insertBefore(s1,s0);
17
  })();
18
  </script>
19
+ <!--End of Tawk.to Script (0.6.0)-->