MDL-65027 core_auth: Implement reCaptcha on forgot password page

This commit is contained in:
meirzamoodle
2025-07-14 16:40:02 +07:00
parent 9addea9f0a
commit e1060d230d
4 changed files with 45 additions and 4 deletions
+9
View File
@@ -157,6 +157,15 @@ if ($hassiteconfig) {
],
));
// Forgot password ReCaptcha.
$temp->add(new admin_setting_configcheckbox(
'enableforgotpasswordrecaptcha',
new lang_string('auth_forgotpasswordrecaptcha', 'auth'),
new lang_string('auth_forgotpasswordrecaptcha_desc', 'auth'),
0,
));
$setting = new admin_setting_configtext('recaptchapublickey', new lang_string('recaptchapublickey', 'admin'), new lang_string('configrecaptchapublickey', 'admin'), '', PARAM_NOTAGS);
$setting->set_force_ltr(true);
$temp->add($setting);
+2
View File
@@ -34,6 +34,8 @@ $string['auth_fieldlock_expl'] = '<p>Lock value: If enabled, users will not be a
$string['auth_fieldlocks'] = 'Lock user fields';
$string['auth_fieldlocks_help'] = '<p>You can lock user data fields. This is useful for sites where the user data is maintained by the administrators manually by editing user records or uploading using the \'Upload users\' facility. If you are locking fields that are required by Moodle, make sure that you provide that data when creating user accounts or the accounts will be unusable.</p><p>Consider setting the lock mode to \'Unlocked if empty\' to avoid this problem.</p>';
$string['auth_fieldmapping'] = 'Data mapping ({$a})';
$string['auth_forgotpasswordrecaptcha'] = 'Enable reCAPTCHA for forgot password';
$string['auth_forgotpasswordrecaptcha_desc'] = 'Add a visual/audio confirmation form element to the forgot password page. This reduces the risk of unwarranted forgotten password attempts. See <a target="_blank" href="https://www.google.com/recaptcha">Google reCAPTCHA</a> for more details.';
$string['auth_changepasswordhelp'] = 'Change password help';
$string['auth_changepasswordhelp_expl'] = 'Display lost password help to users who have lost their {$a} password. This will be displayed either as well as or instead of the <strong>Change Password URL</strong> or Internal Moodle password change.';
$string['auth_changepasswordurl'] = 'Change password URL';
+10
View File
@@ -1115,6 +1115,16 @@ function login_captcha_enabled(): bool {
return !empty($CFG->recaptchapublickey) && !empty($CFG->recaptchaprivatekey) && $CFG->enableloginrecaptcha == true;
}
/**
* Checks if the captcha is enabled for the forgot password feature.
*
* @return bool True if captcha is enabled, false otherwise.
*/
function forgotpassword_captcha_enabled(): bool {
global $CFG;
return !empty($CFG->recaptchapublickey) && !empty($CFG->recaptchaprivatekey) && $CFG->enableforgotpasswordrecaptcha == true;
}
/**
* Check the submitted captcha is valid or not.
*
+24 -4
View File
@@ -56,17 +56,25 @@ class login_forgot_password_form extends moodleform {
$mform->addElement('text', 'username', get_string('username'), 'size="20"' . $purpose);
$mform->setType('username', PARAM_RAW);
$submitlabel = get_string('search');
$mform->addElement('submit', 'submitbuttonusername', $submitlabel);
$mform->addElement('header', 'searchbyemail', get_string('searchbyemail'), '');
$purpose = user_edit_map_field_purpose($USER->id, 'email');
$mform->addElement('text', 'email', get_string('email'), 'maxlength="100" size="30"' . $purpose);
$mform->setType('email', PARAM_RAW_TRIMMED);
// Avoid the user to fill both fields.
$mform->disabledIf('email', 'username', 'neq', '');
$mform->disabledIf('username', 'email', 'neq', '');
$mform->addElement('html', '<hr />');
// Adds a reCAPTCHA element to the forgot password form if the forgot password captcha is enabled.
if (forgotpassword_captcha_enabled()) {
$mform->addElement('recaptcha', 'recaptcha_element', '');
}
$submitlabel = get_string('search');
$mform->addElement('submit', 'submitbuttonemail', $submitlabel);
$mform->addElement('submit', 'submit', $submitlabel);
}
/**
@@ -79,6 +87,18 @@ class login_forgot_password_form extends moodleform {
$errors = parent::validation($data, $files);
if (forgotpassword_captcha_enabled()) {
$recaptchaelement = $this->_form->getElement('recaptcha_element');
if (!empty($this->_form->_submitValues['g-recaptcha-response'])) {
$response = $this->_form->_submitValues['g-recaptcha-response'];
if (!$recaptchaelement->verify($response)) {
$errors['recaptcha_element'] = get_string('incorrectpleasetryagain', 'auth');
}
} else {
$errors['recaptcha_element'] = get_string('missingrecaptchachallengefield');
}
}
// Extend validation for any form extensions from plugins.
$errors = array_merge($errors, core_login_validate_extend_forgot_password_form($data));