-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature/secure-mode-support #39
base: master
Are you sure you want to change the base?
Conversation
WalkthroughThe changes in this pull request encompass updates across multiple files to enhance the functionality and security of the Tawk.to plugin. Key modifications include the addition of a root property in the ESLint configuration, new visitor recognition features in JavaScript, the introduction of a JavaScript API key in the configuration, and significant updates to the TawkTo_Settings class for improved data handling and encryption. Additionally, a new input field for the API key has been integrated into the settings template, along with various refinements to the user interface and validation processes. Changes
Poem
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
🧹 Outside diff range and nitpick comments (6)
tawkto/includes/default_config.php (1)
19-19
: Consider separating security configurations from visibility settingsThe
js_api_key
is placed within thevisibility
array, but it's a security credential rather than a visibility setting. Consider creating a separatesecurity
orauthentication
configuration section to better organize and maintain security-related settings.return array( 'visibility' => array( 'always_display' => 1, // ... other visibility settings ... - 'js_api_key' => '', ), + 'security' => array( + 'js_api_key' => '', + ), );tawkto/assets/js/tawk.admin.js (3)
76-82
: Consider clearing the API key field when disabledWhen visitor recognition is disabled, consider clearing the API key field value in addition to disabling it. This prevents any stored API key from being visible in the DOM when the feature is disabled.
if ( jQuery( '#enable-visitor-recognition' ).prop( 'checked' ) ) { jQuery( '.tawk-selected-visitor' ).show(); jQuery( '#js-api-key' ).prop( 'disabled', false ); } else { jQuery( '.tawk-selected-visitor' ).hide(); jQuery( '#js-api-key' ).prop( 'disabled', true ); + jQuery( '#js-api-key' ).val(''); }
84-94
: Enhance change handler implementationTwo suggestions for improvement:
- Clear the API key field when disabling visitor recognition
- Add a consistent animation duration for better UX alignment with other animations in the file
jQuery( '#enable-visitor-recognition' ).change( function() { if ( this.checked ) { - jQuery( '.tawk-selected-visitor' ).fadeIn(); + jQuery( '.tawk-selected-visitor' ).fadeIn(400); jQuery( '#js-api-key' ).prop( 'disabled', false ); } else { - jQuery( '.tawk-selected-visitor' ).fadeOut(); + jQuery( '.tawk-selected-visitor' ).fadeOut(400); jQuery( '#js-api-key' ).prop( 'disabled', true ); + jQuery( '#js-api-key' ).val(''); } } );
75-94
: Consider additional security measures for API key handlingSince this code handles sensitive API key information, consider implementing these security measures:
- Add input validation for the API key format
- Consider implementing a secure way to test the API key validity
- Ensure the API key is properly sanitized before being saved
Would you like assistance in implementing any of these security measures?
tawkto/templates/settings.php (1)
416-423
: Enhance the notice with additional context and documentationConsider adding a link to the Tawk.to documentation about Secure Mode and its benefits to help users make informed decisions.
<p class='tawk-notice'> <?php esc_html_e( 'Note: If ', 'tawk-to-live-chat' ); ?> <b><?php esc_html_e( 'Secure Mode', 'tawk-to-live-chat' ); ?></b> <?php esc_html_e( ' is enabled on your property, please enter your ', 'tawk-to-live-chat' ); ?> <b><?php esc_html_e( 'Javascript API Key', 'tawk-to-live-chat' ); ?></b> <?php esc_html_e( ' for visitor recognition to work correctly.', 'tawk-to-live-chat' ); ?> + <br/> + <a href="https://www.tawk.to/knowledgebase/secure-mode" target="_blank" rel="noopener noreferrer"> + <?php esc_html_e( 'Learn more about Secure Mode', 'tawk-to-live-chat' ); ?> + </a> </p>tawkto/tawkto.php (1)
30-31
: Useopenssl_cipher_iv_length()
to determine IV length instead of hardcodingTo ensure compatibility with the specified cipher and improve maintainability, consider using
openssl_cipher_iv_length(self::CIPHER)
to dynamically determine the IV length instead of hardcodingCIPHER_IV_LENGTH
as16
. This approach ensures that the IV length always matches the requirements of the cipher algorithm.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (5)
.eslintrc.js
(1 hunks)tawkto/assets/js/tawk.admin.js
(1 hunks)tawkto/includes/default_config.php
(1 hunks)tawkto/tawkto.php
(5 hunks)tawkto/templates/settings.php
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- .eslintrc.js
🔇 Additional comments (2)
tawkto/includes/default_config.php (1)
19-19
: Verify secure handling of the API key
Since this is a sensitive credential being introduced as part of secure mode support, let's verify the implementation of proper security measures in the related files.
✅ Verification successful
Let me verify the encryption functions to ensure complete security. I'll check the implementation of encryption/decryption methods.
Let me try a different approach to check the encryption methods and frontend usage.
Let me check one final aspect about the cipher configuration and usage.
API key implementation follows security best practices
The implementation shows proper security measures:
- The API key is encrypted using AES-256-CBC with a random IV before storage
- Encryption uses WordPress's SECURE_AUTH_KEY constant
- The key is properly escaped when output in forms
- No direct exposure of the key in JavaScript
- Key is only used server-side for HMAC generation
- Decryption is properly handled with base64 decode and IV separation
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for proper encryption and secure handling of js_api_key
# Check if the key is properly encrypted when stored
rg -A 5 "js_api_key" --type php
# Look for encryption-related functions handling this key
ast-grep --pattern 'function $_($$js_api_key) {
$$$
}'
# Check for any direct/unencrypted usage of the key
rg -i "js_api_key.*=.*['\"]\w+['\"]" --type php
Length of output: 2304
Script:
#!/bin/bash
# Check the implementation of encryption/decryption methods
ast-grep --pattern 'function get_encrypted_data($_) {
$$$
}'
ast-grep --pattern 'function get_decrypted_data($_) {
$$$
}'
# Check how the key is used in frontend/output
rg -A 3 "wp_localize_script.*js_api" --type php
Length of output: 179
Script:
#!/bin/bash
# Search for encryption-related functions in the class
rg -A 10 "function get_(en|de)crypted_data" --type php
# Check how the API key is passed to frontend
rg -A 5 "wp_localize_script|wp_add_inline_script" --type php
# Look for any direct output of the key
rg "echo.*js_api" --type php
Length of output: 1757
Script:
#!/bin/bash
# Check cipher configuration
rg -A 2 "CIPHER.*=" --type php
# Check if the key is used in any JavaScript
rg -g "*.js" "js_api|api_key"
# Check for any WordPress hooks/filters related to the key
rg "add_filter|apply_filters.*js_api" --type php
Length of output: 394
tawkto/templates/settings.php (1)
415-438
: Add API key validation and test functionality
Consider adding immediate validation feedback and a test connection feature to help users verify their configuration.
<div class="tawk-selected-visitor">
<!-- ... existing code ... -->
<table class="form-table">
<tr valign="top">
<th class="tawk-setting" scope="row">
<?php esc_html_e( 'Javascript API Key', 'tawk-to-live-chat' ); ?>
</th>
<td>
<input type="password"
id="js-api-key"
name="tawkto-visibility-options[js_api_key]"
value="<?php echo esc_attr( $visibility['js_api_key'] ); ?>" />
+ <button type="button"
+ class="button"
+ id="test-api-key"
+ onclick="testApiKey()"
+ <?php echo empty($visibility['js_api_key']) ? 'disabled' : ''; ?>>
+ <?php esc_html_e( 'Test Connection', 'tawk-to-live-chat' ); ?>
+ </button>
+ <p class="description" id="js-api-key-status"></p>
</td>
</tr>
</table>
</div>
Add this JavaScript to handle the test functionality:
function testApiKey() {
const apiKey = document.getElementById('js-api-key').value;
const statusEl = document.getElementById('js-api-key-status');
// Show loading state
statusEl.textContent = 'Testing connection...';
// Make an AJAX call to test the API key
// This requires implementing an endpoint in the plugin's PHP code
jQuery.post(ajaxurl, {
action: 'test_tawkto_api_key',
api_key: apiKey,
nonce: tawktoSettings.nonce
})
.done(function(response) {
if (response.success) {
statusEl.style.color = '#00a32a';
statusEl.textContent = 'Connection successful!';
} else {
statusEl.style.color = '#d63638';
statusEl.textContent = response.data.message || 'Connection failed!';
}
})
.fail(function() {
statusEl.style.color = '#d63638';
statusEl.textContent = 'Connection test failed. Please try again.';
});
}
// Enable/disable test button based on API key input
document.getElementById('js-api-key').addEventListener('input', function() {
document.getElementById('test-api-key').disabled = !this.value;
});
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (3)
tawkto/tawkto.php (1)
376-403
: Improve error handling in encryption method.While the method handles basic error cases, it could be enhanced:
- Add logging for encryption failures
- Consider throwing exceptions instead of returning empty strings
private static function get_encrypted_data( $data ) { try { $iv = random_bytes( self::CIPHER_IV_LENGTH ); } catch ( Exception $e ) { + error_log( 'Failed to generate IV: ' . $e->getMessage() ); return ''; } $encrypted_data = openssl_encrypt( $data, self::CIPHER, SECURE_AUTH_KEY, 0, $iv ); if ( false === $encrypted_data ) { + error_log( 'Failed to encrypt data with OpenSSL' ); return ''; } // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode $encrypted_data = base64_encode( $iv . $encrypted_data ); if ( false === $encrypted_data ) { + error_log( 'Failed to base64 encode encrypted data' ); return ''; } return $encrypted_data; }tawkto/templates/settings.php (2)
418-422
: Typographical correction: 'Javascript' should be 'JavaScript'In the notice text, "Javascript API Key" should be spelled "JavaScript API Key" to reflect the correct spelling of "JavaScript".
428-428
: Typographical correction: 'Javascript' should be 'JavaScript'In the label, "Javascript API Key" should be updated to "JavaScript API Key" for accurate spelling.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (2)
tawkto/tawkto.php
(5 hunks)tawkto/templates/settings.php
(1 hunks)
🔇 Additional comments (8)
tawkto/tawkto.php (5)
30-31
: LGTM! Encryption configuration looks secure.
The chosen cipher (AES-256-CBC) and IV length (16 bytes) follow cryptographic best practices.
254-254
: Consider using a more appropriate sanitization method for API keys.
The current implementation uses sanitize_text_field()
which might alter special characters in the API key.
Also applies to: 335-339
436-444
: LGTM! API key getter implementation is secure.
The method properly handles missing or invalid API keys by returning an empty string.
543-548
: LGTM! Secure implementation of visitor recognition.
The code correctly:
- Checks for empty email and API key before computing hash
- Uses HMAC-SHA256 for secure hash generation
411-429
: 🛠️ Refactor suggestion
Add input validation in decryption method.
The method should validate the input length before attempting decryption.
private static function get_decrypted_data( $data ) {
+ if ( empty( $data ) ) {
+ return '';
+ }
+
// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode
$decoded_data = base64_decode( $data );
if ( false === $decoded_data ) {
+ error_log( 'Failed to base64 decode encrypted data' );
return '';
}
+ if ( strlen( $decoded_data ) <= self::CIPHER_IV_LENGTH ) {
+ error_log( 'Decoded data is too short' );
+ return '';
+ }
$iv = substr( $decoded_data, 0, self::CIPHER_IV_LENGTH );
$encrypted_data = substr( $decoded_data, self::CIPHER_IV_LENGTH );
$decrypted_data = openssl_decrypt( $encrypted_data, self::CIPHER, SECURE_AUTH_KEY, 0, $iv );
if ( false === $decrypted_data ) {
+ error_log( 'Failed to decrypt data with OpenSSL' );
return '';
}
return $decrypted_data;
}
Likely invalid or redundant comment.
tawkto/templates/settings.php (3)
435-435
: Reconsider the input validation pattern for 'JavaScript API Key'
The current pattern ^[a-zA-Z0-9]+$
allows only letters and digits. If the API key may include other characters such as hyphens or underscores, consider updating the pattern to accommodate them.
You can adjust the pattern as follows:
- pattern="^[a-zA-Z0-9]+$"
+ pattern="^[a-zA-Z0-9-_]+$"
434-436
: Add a placeholder to the API key input field for better user guidance
Including a placeholder can improve user experience by indicating what the user should enter.
You can add the placeholder
attribute:
value="<?php echo esc_attr( $visibility['js_api_key'] ); ?>"
+ placeholder="<?php esc_attr_e( 'Enter your JavaScript API Key', 'tawk-to-live-chat' ); ?>"
pattern="^[a-zA-Z0-9]+$"
431-436
: Enhance the API key input field with a show/hide toggle
Adding a toggle button to show or hide the API key can improve usability while maintaining security.
If you'd like assistance implementing this feature, I can help provide the necessary code or open a GitHub issue.
Summary by CodeRabbit
Release Notes
New Features
Enhancements
Bug Fixes