Simple Memberships - Login Logout Autologin fixes

User avatar
axew3
w3all User
w3all User
Posts: 3103
Joined: Fri Jan 22, 2016 5:15 pm
Location: Italy
Skype: axewww

Simple Memberships - Login Logout Autologin fixes

Post by axew3 »

OBSOLETE: note that since 3.1.6 the easy integration for Simple Membership plugin is available here:

https://www.axew3.com/w3/2025/06/wordpr ... code-file/


NOTE that for WP MU-MS you have to add this step to correctly register an user:
viewtopic.php?p=7235#p7235

To correctly login the user
through the Simple Membership form:


Open wp-w3all.php
and inside the function wp_check_password($password, $hash, $user_id = '') {
(there are two wp_check_password functions into the wp_w3all.php file, maybe apply to both, but mandatory is to add it the first)
search for lines


OBSOLETE: note that since 3.1.6 the easy integration for Simple Membership plugin is available here:

https://www.axew3.com/w3/2025/06/wordpr ... code-file/

Code: Select all

# going to use a direct query in place of get_user_by() before, or the pass hash in this case will not match
$wpu_db_utab = (is_multisite()) ? WPW3ALL_MAIN_DBPREFIX . 'users' : $wpdb->prefix . 'users';
$wpu = $wpdb->get_row("SELECT * FROM $wpu_db_utab WHERE ID = '".$user_id."'");
 
Just after add this code:

Code: Select all

if( empty($wpu) && !empty($_POST['swpm_user_name']) ){
  $wpu = get_user_by( 'login', sanitize_user( $_POST['swpm_user_name'] ) );	
  $user_id = empty($wpu->ID) ? '' : $wpu->ID;
}

To correctly logout the user
on same wp-w3all.php file search for

Code: Select all

add_action( 'wp_logout', array( 'WP_w3all_phpbb', 'wp_w3all_phpbb_logout' ) );
Just after add this:

Code: Select all

add_action('clear_auth_cookie', array( 'WP_w3all_phpbb', 'wp_w3all_phpbb_logout' ) );

To autologin the user after registration
open the file /wp-w3all-phpbb-integration/class.wp.w3all-phpbb.php
and search for the commented lines that starts with

Code: Select all

// FIX AUTOLOGIN for woocommerce or any other plugin:
Just after add this:

Code: Select all

# Available vars to check that we are on Simple Memberships action
# 'swpm_registration_submit'  'swpm_membership_level'  'swpm_level_hash' 
# and maybe 'level_identifier'

 if( isset($_POST['swpm_registration_submit']) && isset($_POST['password']) )
 {
   if( wp_check_password($_POST['password'], $wpu->user_pass, $wpu->ID) )
    {
      self::phpBB_user_session_set_res($wpu);
      wp_safe_redirect( home_url() );
      exit;
    }
 }
Note that home_url() can be any other URL, for example

wp_redirect( home_url( '/my-profile/' ) );
or the default wp user dashboard
wp_redirect( admin_url('profile.php') );
that so maybe will automatically redirected to some front end user's profile page by some other plugin that hide the default WP dashboard to normal users redirecting to his own front-end profile page.

To login the user by phpBB cookie
viewtopic.php?p=7239#p7239
pennymachines
w3 User
w3 User
Posts: 112
Joined: Mon Feb 06, 2017 9:51 pm

Re: Simple Memberships - Login Logout Autologin fixes

Post by pennymachines »

Please find attached w3all-SWPM-bridge.php.
This is placed in the Wordpress mu-plugins folder and is designed to handle all the issues connected with integrating the Simple Membership plugin (on a WP multisite) with w3all. The advantage of this method is that it avoids modifying any w3all code.
* Plugin Name: PM w3all / Simple Membership bridge
* Description: Everything we need on top of stock w3all, kept OUTSIDE the
* w3all plugin files so w3all can be updated without re-patching.
*
* INSTALL: wp-content/mu-plugins/w3all-SWPM-bridge.php
* (must-use plugins load BEFORE regular plugins, which is what lets this
* file get in ahead of w3all's early 'plugins_loaded' login check - a theme's
* functions.php is loaded too late for any of this.)
*
* CONTENTS
* A. Keep visitors on the page they asked for after w3all's first auto-login.
* B. Log into Simple Membership from an existing WP session (subsite where Simple Membership is installed only).
* [replaces old w3all patch MOD 2]
* C. Run w3all's phpBB check at 'plugins_loaded' on the front end.
* [replaces old w3all patch MOD 6]
* D. Log out of phpBB whenever WordPress clears its auth cookie.
* [replaces old w3all patches MOD 5 and MOD 1]
* E. Let Simple Membership's own login form pass w3all's password check.
* [replaces old w3all patch MOD 4]
* F. After a Simple Membership registration, start the phpBB session.
* [replaces old w3all patch MOD 3]
* G. After a menu logout, return to the page the visitor logged out from.
* (w3all's own logout redirect fires before the theme's functions.php loads.)
*
As it was created with help from AI, I cannot vouch for its security. If Allessio has time to look at it, maybe he can...
User avatar
axew3
w3all User
w3all User
Posts: 3103
Joined: Fri Jan 22, 2016 5:15 pm
Location: Italy
Skype: axewww

Re: Simple Memberships - Login Logout Autologin fixes

Post by axew3 »

Hi! Thank you! Going to test asap, i downloaded yesterday immediately, but having problem with Hostinger and a site i follow so i had not the time to check it until now.
Do you changed the file? I just re-downloaded anyway and we can see that

1. Arbitrary External Redirect in Section F (Open Redirect)
changed to

Code: Select all

            $forum_url = isset( $GLOBALS['w3all_url_to_cms'] ) ? trim( (string) $GLOBALS['w3all_url_to_cms'] ) : '';
            if ( preg_match( '#^https?://#i', $forum_url ) ) {
                wp_safe_redirect( trailingslashit( $forum_url ) );
                ....
2. Network-Bypass Open Redirect in Section G (Open Redirect via Host Spoofing)

In Section G (menu logout), the code parses the redirect_to parameter from the URL query string and attempts to validate that it stays on the same network:

Code: Select all

$target = str_replace( array( '&', '&' ), '&', wp_unslash( (string) $_GET['redirect_to'] ) );
$parts  = wp_parse_url( $target );
...
$net_host = wp_parse_url( network_home_url(), PHP_URL_HOST );
if ( ! $net_host || preg_replace( '/^www\./', '', strtolower( $parts['host'] ) ) !== preg_replace( '/^www\./', '', strtolower( $net_host ) ) ) {
    return $location;
}
return $target;
Relying purely on wp_parse_url() to validate a destination URL for safe redirects is highly dangerous and prone to parser differential bugs.

Code: Select all

add_filter( 'wp_redirect', function ( $location, $status ) {

    if ( did_action( 'init' ) ) {
        return $location; // Later redirects are handled by the theme's own filter.
    }
    if ( ! isset( $_GET['action'], $_GET['pm_modal_logout'], $_GET['redirect_to'] ) || 'logout' !== $_GET['action'] ) {
        return $location;
    }
    // Only replace w3all's default "go to the home page" redirect.
    if ( untrailingslashit( (string) $location ) !== untrailingslashit( home_url() ) ) {
        return $location;
    }

    // Clean up the raw query parameter input.
    $target = str_replace( array( '&', '&' ), '&', wp_unslash( (string) $_GET['redirect_to'] ) );

    /**
     * SECURE VALIDATION:
     * wp_validate_redirect evaluates if $target is a safe, local destination URL.
     * If it passes security checks, it returns $target.
     * If it fails (external domain, malicious browser exploits, etc.), it returns the fallback parameter ($location).
     */
    return wp_validate_redirect( $target, $location );
}, 2, 2 );
Let's test if it will work this way asap and we'll add it into the addons folder.
User avatar
axew3
w3all User
w3all User
Posts: 3103
Joined: Fri Jan 22, 2016 5:15 pm
Location: Italy
Skype: axewww

Re: Simple Memberships - Login Logout Autologin fixes

Post by axew3 »

Anyway, about this surely wonderful plugin, i do not understand why they leave the installation with all this errors/warnings
like so

Code: Select all

[31-Oct-2026 13:31:19 UTC] PHP Notice:  Function wp_is_block_theme was called <strong>incorrectly</strong>. This function should not be called before the theme directory is registered. Please see <a href="https://developer.wordpress.org/advanced-administration/debug/debug-wordpress/">Debugging in WordPress</a> for more information. (This message was added in version 6.8.0.) in D:/HTDOCS/wp-mums/wp-includes/functions.php on line 6260
The plugin initializes structural constraints, routing blocks, and shortcodes early on.
1. The main file simple-wp-membership.php sets up the SimpleWpMembership class instance right away.
2. The plugin features Gutenberg block compatibility layouts (compiled inside its /js/ folder) and registers custom styling dependencies.
3. During registration or when checking block editor compatibility constraints (e.g., dynamically adjusting styling depending on whether the active environment is a Classic theme vs. a Block theme), it executes wp_is_block_theme() or calls a third-party script/WooCommerce integration helper that invokes it before the after_setup_theme action hook has run.

Why they do not fix the issue like this, may using after_setup_theme to wrap the firing plugin code?

Code: Select all

add_action('after_setup_theme', function() {

//Include the main class file.
include_once( SIMPLE_WP_MEMBERSHIP_PATH . 'classes/class.simple-wp-membership.php' );
//Include the compatibility file (for backward compatibility). It needs to be included after the main class file has included the necessary files.
include_once( SIMPLE_WP_MEMBERSHIP_PATH . 'swpm-compat.php' );//It will be removed in the future.


	if (function_exists('wp_is_block_theme') && wp_is_block_theme()) {
//Perform some initial setup tasks.
SwpmUtils::do_misc_initial_plugin_setup_tasks();

//Register activation and deactivation hooks
register_activation_hook( SIMPLE_WP_MEMBERSHIP_PATH . 'simple-wp-membership.php', 'SimpleWpMembership::activate' );
register_deactivation_hook( SIMPLE_WP_MEMBERSHIP_PATH . 'simple-wp-membership.php', 'SimpleWpMembership::deactivate' );

//Instantiate the main class
$simple_membership = new SimpleWpMembership();
$simple_membership_cron = new SwpmCronJob();

    }
});
into the file /wp-content/plugins/simple-membership/simple-wp-membership.php
it would not work as expected due to hooks instances or what?

PS it is just a test may some instruction can be leaved out of the init ( or after_setup_theme )
User avatar
axew3
w3all User
w3all User
Posts: 3103
Joined: Fri Jan 22, 2016 5:15 pm
Location: Italy
Skype: axewww

Re: Simple Memberships - Login Logout Autologin fixes

Post by axew3 »

Standing on my tests all works fine logging in an user with your snippet included as follow into the wp-w3all.php file (and after i wrapped the main SM code as described above into an init priority 1 or after_setup_theme):

on wp-w3all.php there is this line of code:

Code: Select all

require_once( WPW3ALL_PLUGIN_DIR . 'common/helpers.php' );
i have put the file into the wp-w3all plugin's /common folder, so it is included like this just after the above instruction:

Code: Select all

add_action('init', function() {
    include_once( WPW3ALL_PLUGIN_DIR . 'addons/w3all-SWPM-bridge.php' );
}, 1);

with 1 you are sure it loads before the wp-w3all-phpbb plugin.
Do not know others features, that i will test along this day asap i have some minute, but the login now worked perfect for example!
User avatar
axew3
w3all User
w3all User
Posts: 3103
Joined: Fri Jan 22, 2016 5:15 pm
Location: Italy
Skype: axewww

Re: Simple Memberships - Login Logout Autologin fixes

Post by axew3 »

Forgive me.
All the above seem to be not useful, since i've find out a way to fix all the issues in one simple instruction for the login, and i assume it will be same way for the logout. Your file will be removed.

Look, the problem come out because, substantially, Simple Membership login an user his own way, not checked if using the default WP check pass (i assume yes before it is overwritten by w3all) or his own, anyway when the login flow reach the wp_w3all.php function wp_check_password the $user_id is empty, the authentication fails, and the user is logged out.

To fix it, we just can check for $_POST adding this into the function wp_check_password:

Just after the line:
$hash_x_wp = $hash;

Adding this and removing a not required check:

Code: Select all

   # Simple Membership fix login

   if( !empty($_POST['swpm_login_origination_flag']) && !empty($_POST['swpm-login']) && !empty($_POST['swpm_password']) )
   {
     $auth = SwpmAuth::get_instance();

      if (!$auth->is_logged_in()) {

        if ( is_email( $_POST['swpm_user_name'] ) ) {
         $user = get_user_by( 'email', $_POST['swpm_user_name'] );
        } else {
            $user = get_user_by( 'login', $_POST['swpm_user_name'] );
          }

         $user_id = ! empty( $user ) ? $user->ID : $user_id;
      }
    }
I see that doing this, there is no need to change nothing else and all works fine.
We can add a custom file inclusion, because maybe not only Simple Membership could have this behavior, so that it will be easy for anyone to add the correct snippet, checking for existent $_POST variables.
Think that this way, instead of a dedicated one for Simple Membership, that anyway will be added into as code example by default, could be the best way for any future simple solution for any plugin maybe?

3.1.6 fixing several little issues is coming just looking to the best way (in absence of more suggestions) to add this and it will be released. What you think?