Skip to content

Commit

Permalink
Added notice to ensure that the site's api version will be the correc…
Browse files Browse the repository at this point in the history
…t one - calls out for action to reconnect site if its not * Corrected the code that gets the user's patronage info and maps it to correct parameters - now it wont fail if the patronage entry does not include campaign id * Added nonce to disconnect Patreon user account action for security
  • Loading branch information
codebard committed Nov 29, 2024
1 parent bd5d432 commit 0d3c7b6
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 17 deletions.
9 changes: 8 additions & 1 deletion assets/js/admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
var patreon_wordpress_nonce_patron_content_manager_addon_notice_shown = jQuery( this ).parent().attr( 'patreon_wordpress_nonce_patron_content_manager_addon_notice_shown' );
var patreon_wordpress_nonce_rate_plugin_notice = jQuery( this ).parent().attr( 'patreon_wordpress_nonce_rate_plugin_notice' );
var patreon_wordpress_nonce_plugin_critical_issues = jQuery( this ).parent().attr( 'patreon_wordpress_nonce_plugin_critical_issues' );
var patreon_wordpress_nonce_patreon_api_version_update = jQuery(this).parent().attr( 'patreon_wordpress_nonce_patreon_api_version_update' );
jQuery.ajax({
url: ajaxurl,
type:"POST",
Expand All @@ -23,6 +24,7 @@
patreon_wordpress_nonce_patron_pro_addon_notice_shown: patreon_wordpress_nonce_patron_pro_addon_notice_shown,
patreon_wordpress_nonce_patron_content_manager_addon_notice_shown: patreon_wordpress_nonce_patron_content_manager_addon_notice_shown,
patreon_wordpress_nonce_plugin_critical_issues: patreon_wordpress_nonce_plugin_critical_issues,
patreon_wordpress_nonce_patreon_api_version_update: patreon_wordpress_nonce_patreon_api_version_update,
}
});
});
Expand Down Expand Up @@ -372,12 +374,17 @@
data: {
action: 'patreon_wordpress_disconnect_patreon_account',
patreon_disconnect_user_id: jQuery( this ).attr( 'patreon_disconnect_user_id' ),
patreon_wordpress_nonce_disconnect_user_account_from_patreon: jQuery(this).attr( 'patreon_wordpress_nonce_disconnect_user_account_from_patreon' ),
},
beforeSend: function(e) {
jQuery( '#patreon_wordpress_user_profile_account_connection_wrapper' ).html( 'A moment...' );
},
success: function( response ) {
jQuery( '#patreon_wordpress_user_profile_account_connection_wrapper' ).html( response );
var message = response;
if (response == 0 ) {
message = 'This form seems to have expired - please refresh the form and Disconnect again';
}
jQuery('#patreon_wordpress_user_profile_account_connection_wrapper').html(message );
},
});

Expand Down
8 changes: 4 additions & 4 deletions classes/patreon_api_v2.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public function fetch_user() {

// We construct the old return from the new returns by combining /me and pledge details

$api_return = $this->__get_json( "identity?include=memberships.currently_entitled_tiers,memberships.campaign&fields[user]=email,first_name,full_name,image_url,last_name,thumb_url,url,vanity,is_email_verified&fields[member]=currently_entitled_amount_cents,lifetime_support_cents,campaign_lifetime_support_cents,last_charge_status,patron_status,last_charge_date,pledge_relationship_start,pledge_cadence" );
$api_return = $this->__get_json( "identity?include=memberships.currently_entitled_tiers,memberships.campaign&fields[user]=email,first_name,full_name,image_url,last_name,thumb_url,url,vanity,is_email_verified&fields[member]=currently_entitled_amount_cents,lifetime_support_cents,campaign_lifetime_support_cents,last_charge_status,patron_status,last_charge_date,pledge_relationship_start,pledge_cadence" );

$creator_id = get_option( 'patreon-creator-id', false );
$campaign_id = get_option( 'patreon-campaign-id', false );
Expand All @@ -31,7 +31,7 @@ public function fetch_user() {

foreach ($api_return['included'] as $key => $value) {

if ( $api_return['included'][$key]['type'] == 'member' AND $api_return['included'][$key]['relationships']['campaign']['data']['id'] == $campaign_id ) {
if ( $api_return['included'][$key]['type'] == 'member' AND ( isset( $api_return['included'][$key]['relationships']['campaign'] ) AND $campaign_id AND $api_return['included'][$key]['relationships']['campaign']['data']['id'] == $campaign_id ) ) {

// The below procedure will take take the matching membership out of the array, put it to the top and reindex numberic keys. This will allow backwards compatibility to be kept
$membership = $api_return['included'][$key];
Expand All @@ -43,7 +43,7 @@ public function fetch_user() {
$api_return['included'][0]['type'] = 'pledge';
$api_return['included'][0]['attributes']['amount_cents'] = $api_return['included'][0]['attributes']['currently_entitled_amount_cents'];
$api_return['included'][0]['attributes']['created_at'] = $api_return['included'][0]['attributes']['pledge_relationship_start'];
$api_return['included'][0]['attributes']['lifetime_support_cents'] = $api_return['included'][0]['attributes']['campaign_lifetime_support_cents'];
$api_return['included'][0]['attributes']['lifetime_support_cents'] = $api_return['included'][0]['attributes']['campaign_lifetime_support_cents'];

if ( $api_return['included'][0]['attributes']['last_charge_status'] != 'Paid' ) {
$api_return['included'][0]['attributes']['declined_since'] = $api_return['included'][0]['attributes']['last_charge_date'];
Expand Down Expand Up @@ -165,7 +165,7 @@ public function add_post_webhook( $params = array() ) {

if ( is_wp_error( $check_url ) ) {
return;
}
}

$postfields = array(
'data' => array (
Expand Down
4 changes: 4 additions & 0 deletions classes/patreon_login.php
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,10 @@ public static function get_update_user_patreon_avatar( $patreon_image_url, $user
public static function disconnect_account_from_patreon() {

// Disconnects an account from Patreon.

if ( !isset($_REQUEST['patreon_wordpress_nonce_disconnect_user_account_from_patreon']) OR !wp_verify_nonce( sanitize_key( $_REQUEST['patreon_wordpress_nonce_disconnect_user_account_from_patreon'] ), 'patreon_wordpress_nonce_disconnect_user_account_from_patreon' ) ) {
return;
}

$user = wp_get_current_user();

Expand Down
2 changes: 1 addition & 1 deletion classes/patreon_user_profiles.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ function patreon_user_profile_fields( $user ) {
<tr>
<th><label id="patreon_wordpress_disconnect_patreon_account_label" for="patreon_user"><?php echo $disconnect_label; ?></label></th>
<td id="patreon_wordpress_disconnect_patreon_account_content">
<button id="patreon_wordpress_disconnect_patreon_account" patreon_disconnect_user_id="<?php echo $user_id; ?>" class="button button-primary button-large" target="">Disconnect from Patreon</button><br /><br /><?php echo $disconnect_warning; ?>
<button id="patreon_wordpress_disconnect_patreon_account" patreon_disconnect_user_id="<?php echo $user_id; ?>" class="button button-primary button-large" target="" patreon_wordpress_nonce_disconnect_user_account_from_patreon="<?php echo wp_create_nonce('patreon_wordpress_nonce_disconnect_user_account_from_patreon'); ?>">Disconnect from Patreon</button><br /><br /><?php echo $disconnect_warning; ?>
</td>
</tr>
</table>
Expand Down
40 changes: 34 additions & 6 deletions classes/patreon_wordpress.php
Original file line number Diff line number Diff line change
Expand Up @@ -956,7 +956,7 @@ public static function AdminMessages() {

$setup_wizard_notice_dismissed = get_option( 'patreon-setup-wizard-notice-dismissed', false );

if( !$setup_done AND !$setup_wizard_notice_dismissed AND ( $api_version AND $api_version == '2' ) AND current_user_can( 'manage_options' ) ) {
if( !$setup_done AND !$setup_wizard_notice_dismissed AND current_user_can( 'manage_options' ) ) {
// This notice needs a nonce but the link to start setup doesnt need a nonce - any admin level user with manage options should be able to go to the setup wizard from anywhere
?>
<div class="notice notice-success is-dismissible patreon-wordpress" id="patreon_setup_needed_notice" patreon_wordpress_nonce_setup_needed="<?php echo wp_create_nonce('patreon_wordpress_nonce_setup_needed'); ?>">
Expand All @@ -967,7 +967,25 @@ public static function AdminMessages() {
// Dont show any more notices until setup is done
return;
}


// Important notice to ensure that the plugin is using the correct version of the api

$api_version_notice_dismissed = get_option( 'api-version-update-notice-dismissed', false );
$api_version_notice_dismissed_time = get_option( 'api-version-update-notice-dismissed-time', 0 );


if( $setup_done AND ( !$api_version OR $api_version == '' OR $api_version == '1' ) AND current_user_can( 'manage_options' ) AND (!$api_version_notice_dismissed OR (!$api_version_notice_dismissed_time OR $api_version_notice_dismissed_time < (time()-(24*3600*7)))) ) {
// This notice needs a nonce but the link to start setup doesnt need a nonce - any admin level user with manage options should be able to go to the setup wizard from anywhere
?>
<div class="notice notice-warning is-dismissible patreon-wordpress" id="patreon_wordpress_patreon_api_version_update_notice" patreon_wordpress_nonce_patreon_api_version_update="<?php echo wp_create_nonce('patreon_wordpress_nonce_patreon_api_version_update'); ?>">
<p>Your site's connection to Patreon must be upgraded to ensure that Patreon features will work! Please click <a href="<?php echo admin_url( 'admin.php?page=patreon_wordpress_setup_wizard&setup_stage=0' ) ?>" target="_self">here</a> to start the setup wizard to reconnect your site again</p>
</div>
<?php

// Dont show any more notices until reconnection is done
return;
}

$already_showed_non_system_notice = false;

// Wp org wants non-error / non-functionality related notices to be shown infrequently and one per admin-wide page load, and be dismissable permanently.
Expand Down Expand Up @@ -1121,6 +1139,16 @@ public function dismiss_admin_notice() {
delete_option( 'patreon-wordpress-app-credentials-failure');
}

// Mapping what comes from REQUEST to a given value avoids potential security problems
if ( $_REQUEST['notice_id'] == 'patreon_wordpress_patreon_api_version_update_notice' ) {
if ( !isset($_REQUEST['patreon_wordpress_nonce_patreon_api_version_update']) OR !wp_verify_nonce( sanitize_key( $_REQUEST['patreon_wordpress_nonce_patreon_api_version_update'] ), 'patreon_wordpress_nonce_patreon_api_version_update' ) ) {
return;
}

update_option( 'api-version-update-notice-dismissed', true );
update_option( 'api-version-update-notice-dismissed-time', time());
}

// Mapping what comes from REQUEST to a given value avoids potential security problems
if ( $_REQUEST['notice_id'] == 'patreon-rate-plugin-notice-shown' ) {

Expand Down Expand Up @@ -1577,7 +1605,7 @@ public static function lock_or_not( $post_id = false ) {
// Just bail out if this is not the main query for content and no post id was given
if ( !is_main_query() AND !$post_id ) {

return self::add_to_lock_or_not_results( $post_id, apply_filters(
return self::add_to_lock_or_not_results( $post_id, apply_filters(
'ptrn/lock_or_not',
array(
'lock' => false,
Expand Down Expand Up @@ -1969,9 +1997,9 @@ public static function setup_wizard() {

echo '<a href="https://support.patreon.com/hc/en-us/articles/360032409172-Patreon-WordPress-Quickstart?utm_source=' . urlencode( site_url() ) . '&utm_medium=patreon_wordpress_plugin&utm_campaign=&utm_content=setup_wizard_screen_3_quickstart_article_link&utm_term=" target="_blank"><div class="patreon_success_insert"><div class="patreon_success_insert_logo"><img src="' . PATREON_PLUGIN_ASSETS . '/img/Learn-how-to-use-Patreon-WordPress.jpg" /></div><div class="patreon_success_insert_heading"><h3>Quickstart guide</h3></div><div class="patreon_success_insert_content"><br clear="both">Click here to read our quickstart guide and learn how to lock your content</div></div></a>';

echo '<a href="https://codebard.com/patron-pro-addon-for-patreon-wordpress?utm_source=' . urlencode( site_url() ) . '&utm_medium=patreon_wordpress_plugin&utm_campaign=&utm_content=setup_wizard_screen_3_patron_pro_pitch_link&utm_term=" target="_blank"><div class="patreon_success_insert"><div class="patreon_success_insert_logo"><img src="' . PATREON_PLUGIN_ASSETS . '/img/Patron-Plugin-Pro-120.png" /></div><div class="patreon_success_insert_heading"><h3>Patron Plugin Pro</h3></div><div class="patreon_success_insert_content"><br clear="both">Power up your integration and increase your income with premium addon Patron Plugin Pro</div></div></a>';
echo '<a href="https://codebard.com/patron-pro-addon-for-patreon-wordpress?utm_source=' . urlencode( site_url() ) . '&utm_medium=patreon_wordpress_plugin&utm_campaign=&utm_content=setup_wizard_screen_3_patron_pro_pitch_link&utm_term=" target="_blank"><div class="patreon_success_insert"><div class="patreon_success_insert_logo"><img src="' . PATREON_PLUGIN_ASSETS . '/img/Patron-Plugin-Pro-120.png" /></div><div class="patreon_success_insert_heading"><h3>Patron Plugin Pro</h3></div><div class="patreon_success_insert_content"><br clear="both">Boost your campaign with more Patreon features at your WP site and increase your income with premium addon Patron Plugin Pro</div></div></a>';

echo '<a href="https://wordpress.org/plugins/patron-button-and-widgets-by-codebard/?utm_source=' . urlencode( site_url() ) . '&utm_medium=patreon_wordpress_plugin&utm_campaign=&utm_content=setup_wizard_screen_3_patron_button_wp_repo_link&utm_term=" target="_blank"><div class="patreon_success_insert"><div class="patreon_success_insert_logo"><img src="' . PATREON_PLUGIN_ASSETS . '/img/Patron-Button-Widgets-and-Plugin.png" /></div><div class="patreon_success_insert_heading"><h3>Patron Widgets</h3></div><div class="patreon_success_insert_content"><br clear="both">Add Patreon buttons and widgets to your site with free Widgets addon</div></div></a>';
echo '<a href="https://codebard.com/patreon-button-and-plugin-for-wordpress?utm_source=' . urlencode( site_url() ) . '&utm_medium=patreon_wordpress_plugin&utm_campaign=&utm_content=setup_wizard_screen_3_patron_button_wp_repo_link&utm_term=" target="_blank"><div class="patreon_success_insert"><div class="patreon_success_insert_logo"><img src="' . PATREON_PLUGIN_ASSETS . '/img/Patron-Button-Widgets-and-Plugin.png" /></div><div class="patreon_success_insert_heading"><h3>Patron Widgets</h3></div><div class="patreon_success_insert_content"><br clear="both">Add Patreon buttons and widgets to your site with the free Widgets addon</div></div></a>';

echo '</div>';

Expand Down Expand Up @@ -2225,7 +2253,7 @@ public static function activate( $network_wide ) {
// Check if this site is a v2 site
$api_version = get_option( 'patreon-installation-api-version', false );

if( !$patreon_setup_done AND ( $api_version AND $api_version == '2' ) ) {
if( !$patreon_setup_done ) {
// Setup complete flag not received. Set flag for redirection in next page load
update_option( 'patreon-redirect_to_setup_wizard', true );
}
Expand Down
4 changes: 2 additions & 2 deletions patreon.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Plugin Name: Patreon Wordpress
Plugin URI: https://www.patreon.com/apps/wordpress
Description: Patron-only content, directly on your website.
Version: 1.9.1
Version: 1.9.2
Author: Patreon <[email protected]>
Author URI: https://patreon.com
*/
Expand Down Expand Up @@ -68,7 +68,7 @@
define( "PATREON_CREATOR_BYPASSES_FILTER_MESSAGE", 'This content is for Patrons only, it\'s not locked for you because you are logged in as the Patreon creator' );
define( "PATREON_NO_LOCKING_LEVEL_SET_FOR_THIS_POST", 'Post is already public. If you would like to lock this post, please set a pledge level for it' );
define( "PATREON_NO_POST_ID_TO_UNLOCK_POST", 'Sorry - could not get the post id for this locked post' );
define( "PATREON_WORDPRESS_VERSION", '1.9.1' );
define( "PATREON_WORDPRESS_VERSION", '1.9.2' );
define( "PATREON_WORDPRESS_BETA_STRING", '' );
define( "PATREON_WORDPRESS_PLUGIN_SLUG", plugin_basename( __FILE__ ) );
define( "PATREON_PRIVACY_POLICY_ADDENDUM", '<h2>Patreon features in this website</h2>In order to enable you to use this website with Patreon services, we save certain functionally important Patreon information about you in this website if you log in with Patreon.
Expand Down
18 changes: 15 additions & 3 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ Contributors: patreon, codebard
Tags: patreon, membership, members
Requires at least: 4.0
Requires PHP: 7.4
Tested up to: 6.5.3
Stable tag: 1.9.1
Tested up to: 6.7.1
Stable tag: 1.9.2
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Connect your WordPress site to Patreon and increase your members and pledges!

== Description ==

With Patreon WordPress, you can bring Patreon features to your WordPress website and integrate them to make them work together. You can even easily import your existing Patreon posts and keep your Patreon posts synced to your WP site automatically! Your patron-only content at your WordPress site will encourage your visitors to become your patrons to unlock your content.
Bring Patreon features to your WordPress website and make them work together. You can even easily import your existing Patreon posts and keep your Patreon posts synced to your WP site automatically! Your patron-only content at your WordPress site will encourage your visitors to become your patrons to unlock your content.

You can lock any single post or all of your posts! You can also lock any custom post type. Your visitors can log into your site via Patreon, making it easier for them to use your site in addition to accessing your locked content.

Expand Down Expand Up @@ -79,6 +79,12 @@ It is difficult to protect videos due the intensive bandwidth requirements of h

== Upgrade Notice ==

= 1.9.2 =

* Added notice to ensure that the site's api version will be the correct one - calls out for action to reconnect site if its not
* Corrected the code that gets the user's patronage info and maps it to correct parameters - now it wont fail if the patronage entry does not include campaign id
* Added nonce to disconnect Patreon user account action for security

= 1.9.1 =

* An issue that made it possible to circumvent image locking by sending a specific referrer header was fixed. Now locked images should not allow circumvention of the protection via referer header
Expand Down Expand Up @@ -511,6 +517,12 @@ You can report security bugs through the Patchstack Vulnerability Disclosure Pro

== Changelog ==

= 1.9.2 =

* Added notice to ensure that the site's api version will be the correct one - calls out for action to reconnect site if its not
* Corrected the code that gets the user's patronage info and maps it to correct parameters - now it wont fail if the patronage entry does not include campaign id
* Added nonce to disconnect Patreon user account action for security

= 1.9.1 =

* An issue that made it possible to circumvent image locking by sending a specific referrer header was fixed. Now locked images should not allow circumvention of the protection via referer header
Expand Down

0 comments on commit 0d3c7b6

Please sign in to comment.