wpsharks / s2member

s2Member® Framework (membership management for WordPress®).
64 stars 36 forks source link

Add option to recognize email aliases (via + character) #1183

Closed pdennis33 closed 4 years ago

pdennis33 commented 4 years ago

EXPLANATION OF THE ISSUE

s2Member Pro Version 200301 with WordPress Version 5.3.2 On my website, I use s2Member Pro and I offer a free trial of 2 weeks on an otherwise paid service. I validate the fact that a user has not signed up before by using both username and email address. I do not allow a user to be deleted, just downgraded to Subscriber if they leave. This way if they come back after their first free trial, they would not be able to just keep getting 2 week free trials. When I use s2Member Pro Operations API to call a get_user op, it does not have an option to catch email aliases using the + sign. This allows for the exploitation of 2 week free trials.

STEPS TO REPRODUCE THE ISSUE

Let's say someone's email is my.valid.email@gmail.com. Someone could use Gmail and sign up for endless free trials if they wanted to by using a different username and using emails such as my.valid.email+free1@gmail.com, my.valid.email+free2@gmail.com, my.valid.email+free3@gmail.com and so on.

BEHAVIOR THAT I EXPECTED

I would expect the ability to allow users to register using aliases, as that is not a problem at all and they may have a very valid reason for that. However, when using the get_user op, I would expect at least a True/False flag that allows me to enforce email aliases as duplicates.

BEHAVIOR THAT I OBSERVED

I observed the fact that even when my.valid.email+free1@gmail.com was a registered user, when I used the get_user op using the email address, it returned false using my.valid.email+free2@gmail.com

ADDITIONAL NOTES

I realize if someone REALLY wanted to do this, they could use random email addresses or even sign up for new email accounts each time. This is beside the point though, as those will be a very small percentage and part of the service is email alerts, so they would want a valid email or the service would not be useful.

SUGGESTED ADDITION

This could be an additional $op['data'] parameter, something like 'search_email_aliases' or something, which would basically add to s2member-pro\src\includes\classes\remote-ops-in.inc.php and would be something like instead of: else if(!empty($op['data']['user_email']) && ($_user = get_user_by('email', (string)$op['data']['user_email'])) && !empty($_user->ID)) $user = $_user;

It would be something like else if(!empty($op['data']['user_email'])){ if($op['data']['search_email_aliases']){ $regEx = '/[+].*@/m'; $op['data']['user_email'] = preg_replace($regEx, '@', $op['data']['user_email']); } if ($_user = get_user_by('email', (string)$op['data']['user_email']) && !empty($_user->ID)) $user = $_user; }

I suppose you could even simply add a filter to the get_user function so we could hook the filter and change the $op['data']['user_email'] if needed. The filter would work and would be less intrusive to your code, so I would be happy either way, as long as I could accomplish this check. It seems like a common use case as well and not very unique to me, so it seems reasonable.

Please let me know your thoughts. Thank you! Paul

pdennis33 commented 4 years ago

Actually sorry my suggested solution will not work as-is. I wasn't realizing that obviously if the user's email is an alias, simply stripping out the alias and doing a get_user_by('email', (string)$op['data']['user_email']) will not work. This would seem to be a bit more complex and I'll get a working solution before posting another suggestion. Maybe a user_meta query using my.valid.email+ with a % after to search any user with that start to their email. I'll update once I have something working.

I'd welcome any thoughts on this still. It still seems like a nice addition to the get_user check within s2Member.

pdennis33 commented 4 years ago

I apologize for opening this as an issue. The more I think about it, the more I realize it is not the job of s2Member's Pro API calls to determine if someone is a duplicate or not. The get_user request is intended to get a specific user, which is what it does. It's not meant to check for duplicates, so I'm just using the tool incorrectly. I will just create my own checking function based on user meta_query and leave s2Member as is. Sorry and I will close the issue :)