For a while now our community portal has been having regular yet inconsistent issues with users trying to request a password reset. We have a password reset link exposed which behind the scenes calls Site.forgotPassword(). Normally this takes users to the reset password page where the system already knows which user is setting up the password as the forgotPassword link has session information on it. However it seems that for some users, sometimes, this link doesn't work, and brings them to the forgotPassword page where instead of asking for the security question (and then new password), it will just ask for their username again. This puts them in a loop where they cannot reset their password. Requesting a forgot password again just continues the loop. The user then has to reach out to our support where support will reset their password from the User record itself, which works consistently.
It's difficult to reproduce this issue. We have gone to Salesforce support who gave us a general answer of the link from the email is being expired immediately. I read an article saying this could be due to the user's email server link protection software. However I'm not sure if this is the case, why we can only sometimes reproduce the issue, but not consistently. If the link protection is causing an issue, I would think it would be consistent, not sporadic. I know Salesforce has a setting on the profile to not expire links immediately, however this then brings the user to an intermediate page instead of the reset password page. This won't work for us...
Anyways, it seems that calling the System.resetPassword() sends the same email and flow, however the email link itself looks more like the email link when resetting from the User record directly. Because I cannot right now reproduce the issue, I am not sure if this method will fix the issue, however I'm thinking if we deploy a quick change here, we can see after a week how many people are still stuck in the loop.
My question is from a security perspective, is using System.resetPassword() less safe to expose to a community user? And if it's not safe, how can we fix the issue with Site.forgotPassword()? We have hundreds of thousands of community users, so our support is getting tickets here on a daily basis and they are wanting a fix.
Also think I should mention we have Google reCAPTCHA implemented on our forgot password page so a user must pass that check before they can request a password reset. This adds a little bit more security.