Switch to profile-based password recovery.
This commit is contained in:
parent
de1b160c2b
commit
631d8cb0e6
9 changed files with 250 additions and 54 deletions
|
|
@ -42,6 +42,8 @@
|
||||||
- fix: IP addresses for adminModeSubnets not using X-Forwarded-For properly
|
- fix: IP addresses for adminModeSubnets not using X-Forwarded-For properly
|
||||||
- The Events Calendar is now the new Calendar with some fun new features.
|
- The Events Calendar is now the new Calendar with some fun new features.
|
||||||
All your existing Events Calendars will be migrated automatically.
|
All your existing Events Calendars will be migrated automatically.
|
||||||
|
- Major change: password recovery is now based on profile fields rather than
|
||||||
|
email account access
|
||||||
*** PLEASE READ THE GOTCHAS ***
|
*** PLEASE READ THE GOTCHAS ***
|
||||||
|
|
||||||
7.2.3
|
7.2.3
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,16 @@ save you many hours of grief.
|
||||||
running the entire test suite prior to SVN commits easier to do
|
running the entire test suite prior to SVN commits easier to do
|
||||||
since it won't take so long.
|
since it won't take so long.
|
||||||
|
|
||||||
|
* Password recovery has been redone. It is now based on profile fields
|
||||||
|
rather than email access. Since there's no real way to migrate the
|
||||||
|
latter to one to the other, this upgrade disables password recovery;
|
||||||
|
before enabling it again, use the profile fields editor to set certain
|
||||||
|
fields as required for password recovery. Then any user who enters all
|
||||||
|
of those fields correctly can recover their password. The template
|
||||||
|
variables are also different, so if you have a custom password recovery
|
||||||
|
template, you will have to update it. See the new default password
|
||||||
|
recovery template for an example of how to use the new variables.
|
||||||
|
|
||||||
7.2.0
|
7.2.0
|
||||||
--------------------------------------------------------------------
|
--------------------------------------------------------------------
|
||||||
* NOTE: if you tried to upgrade to 7.2.0 and it failed during the
|
* NOTE: if you tried to upgrade to 7.2.0 and it failed during the
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
#PBtmpl0000000000000014
|
||||||
|
#namespace:Auth/WebGUI/Recovery2
|
||||||
|
<h2><tmpl_var title></h2>
|
||||||
|
|
||||||
|
<tmpl_if recoverMessage><tmpl_var recoverMessage></tmpl_if>
|
||||||
|
|
||||||
|
<tmpl_var recoverFormHeader>
|
||||||
|
<tmpl_var recoverFormHidden>
|
||||||
|
<table>
|
||||||
|
<tmpl_if doingRecovery>
|
||||||
|
<tr>
|
||||||
|
<td class="formDescription" valign="top"><tmpl_var recoverFormPasswordLabel></td>
|
||||||
|
<td class="tableData"><tmpl_var recoverFormPassword></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="formDescription" valign="top"><tmpl_var recoverFormPasswordConfirmLabel></td>
|
||||||
|
<td class="tableData"><tmpl_var recoverFormPasswordConfirm></td>
|
||||||
|
</tr>
|
||||||
|
<tmpl_else>
|
||||||
|
<tmpl_if recoverFormUsername>
|
||||||
|
<tr>
|
||||||
|
<td class="formDescription" valign="top"><tmpl_var recoverFormUsernameLabel></td>
|
||||||
|
<td class="tableData"><tmpl_var recoverFormUsername></td>
|
||||||
|
</tr>
|
||||||
|
</tmpl_if>
|
||||||
|
<tmpl_loop recoverFormProfile>
|
||||||
|
<tr>
|
||||||
|
<td class="formDescription" valign="top"><tmpl_var label></td>
|
||||||
|
<td class="tableData"><tmpl_var formElement></td>
|
||||||
|
</tr>
|
||||||
|
</tmpl_loop>
|
||||||
|
</tmpl_if>
|
||||||
|
<tr>
|
||||||
|
<td class="formDescription" valign="top"></td>
|
||||||
|
<td class="tableData"><tmpl_var recoverFormSubmit></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<tmpl_var recoverFormFooter>
|
||||||
|
|
||||||
|
<div class="accountOptions">
|
||||||
|
<ul>
|
||||||
|
<tmpl_if anonymousRegistrationIsAllowed>
|
||||||
|
<li><a href="<tmpl_var createAccountUrl>"><tmpl_var createAccountLabel></a></li>
|
||||||
|
</tmpl_if>
|
||||||
|
<li><a href="<tmpl_var loginUrl>"><tmpl_var loginLabel></a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
@ -23,6 +23,7 @@ addWikiAssets($session);
|
||||||
deleteOldFiles($session);
|
deleteOldFiles($session);
|
||||||
addFileFieldsToDataForm($session);
|
addFileFieldsToDataForm($session);
|
||||||
makeRSSFromParentAlwaysHidden($session);
|
makeRSSFromParentAlwaysHidden($session);
|
||||||
|
addProfileFieldsOnPasswordRecovery($session);
|
||||||
addNewCalendar($session);
|
addNewCalendar($session);
|
||||||
migrateCalendars($session);
|
migrateCalendars($session);
|
||||||
removeOldCalendar($session);
|
removeOldCalendar($session);
|
||||||
|
|
@ -278,6 +279,20 @@ sub removeOldCalendar {
|
||||||
$session->config->deleteFromArray("assets","WebGUI::Asset::Wobject::EventsCalendar");
|
$session->config->deleteFromArray("assets","WebGUI::Asset::Wobject::EventsCalendar");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#-------------------------------------------------
|
||||||
|
sub addProfileFieldsOnPasswordRecovery {
|
||||||
|
my $session = shift;
|
||||||
|
print "\tAdding requiredForPasswordRecovery to userProfileField rows.\n" unless $quiet;
|
||||||
|
$session->db->write($_) for(<<'EOT',
|
||||||
|
ALTER TABLE userProfileField
|
||||||
|
ADD COLUMN requiredForPasswordRecovery int(11) NOT NULL default '0'
|
||||||
|
EOT
|
||||||
|
);
|
||||||
|
|
||||||
|
$session->setting->set('webguiPasswordRecovery', 0);
|
||||||
|
$session->setting->add('webguiPasswordRecoveryRequireUsername', 1);
|
||||||
|
$session->setting->set('webguiPasswordRecoveryTemplate', 'PBtmpl0000000000000014');
|
||||||
|
}
|
||||||
|
|
||||||
# ---- DO NOT EDIT BELOW THIS LINE ----
|
# ---- DO NOT EDIT BELOW THIS LINE ----
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ sub _hasMixedCaseCharacters {
|
||||||
|
|
||||||
=head2 _isValidPassword ( )
|
=head2 _isValidPassword ( )
|
||||||
|
|
||||||
Validates the password9.
|
Validates the password.
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
|
|
@ -427,11 +427,11 @@ sub editUserSettingsForm {
|
||||||
-value=>$self->session->setting->get("webguiPasswordRecovery"),
|
-value=>$self->session->setting->get("webguiPasswordRecovery"),
|
||||||
-label=>$i18n->get(6)
|
-label=>$i18n->get(6)
|
||||||
);
|
);
|
||||||
$f->textarea(
|
$f->yesNo(
|
||||||
-name=>"webguiRecoverPasswordEmail",
|
-name=>"webguiPasswordRecoveryRequireUsername",
|
||||||
-label=>$i18n->get(134, 'WebGUI'),
|
-value=>$self->session->setting->get("webguiPasswordRecoveryRequireUsername"),
|
||||||
-value=>$self->session->setting->get("webguiRecoverPasswordEmail")
|
-label=>$i18n->get('require username for password recovery')
|
||||||
);
|
);
|
||||||
$f->yesNo(
|
$f->yesNo(
|
||||||
-name=>"webguiValidateEmail",
|
-name=>"webguiValidateEmail",
|
||||||
-value=>$self->session->setting->get("webguiValidateEmail"),
|
-value=>$self->session->setting->get("webguiValidateEmail"),
|
||||||
|
|
@ -469,7 +469,7 @@ sub editUserSettingsForm {
|
||||||
$f->template(
|
$f->template(
|
||||||
-name=>"webguiPasswordRecoveryTemplate",
|
-name=>"webguiPasswordRecoveryTemplate",
|
||||||
-value=>$self->session->setting->get("webguiPasswordRecoveryTemplate"),
|
-value=>$self->session->setting->get("webguiPasswordRecoveryTemplate"),
|
||||||
-namespace=>"Auth/WebGUI/Recovery",
|
-namespace=>"Auth/WebGUI/Recovery2",
|
||||||
-label=>$i18n->get("password recovery template")
|
-label=>$i18n->get("password recovery template")
|
||||||
);
|
);
|
||||||
return $f->printRowsOnly;
|
return $f->printRowsOnly;
|
||||||
|
|
@ -491,7 +491,7 @@ sub editUserSettingsFormSave {
|
||||||
$s->set("webguiChangeUsername", $f->process("webguiChangeUsername","yesNo"));
|
$s->set("webguiChangeUsername", $f->process("webguiChangeUsername","yesNo"));
|
||||||
$s->set("webguiChangePassword", $f->process("webguiChangePassword","yesNo"));
|
$s->set("webguiChangePassword", $f->process("webguiChangePassword","yesNo"));
|
||||||
$s->set("webguiPasswordRecovery", $f->process("webguiPasswordRecovery","yesNo"));
|
$s->set("webguiPasswordRecovery", $f->process("webguiPasswordRecovery","yesNo"));
|
||||||
$s->set("webguiRecoverPasswordEmail", $f->process("webguiRecoverPasswordEmail","textarea"));
|
$s->set("webguiPasswordRecoveryRequireUsername", $f->process("webguiPasswordRecoveryRequireUsername","yesNo"));
|
||||||
$s->set("webguiValidateEmail", $f->process("webguiValidateEmail","yesNo"));
|
$s->set("webguiValidateEmail", $f->process("webguiValidateEmail","yesNo"));
|
||||||
$s->set("webguiUseCaptcha", $f->process("webguiUseCaptcha","yesNo"));
|
$s->set("webguiUseCaptcha", $f->process("webguiUseCaptcha","yesNo"));
|
||||||
$s->set("webguiAccountTemplate", $f->process("webguiAccountTemplate","template"));
|
$s->set("webguiAccountTemplate", $f->process("webguiAccountTemplate","template"));
|
||||||
|
|
@ -570,63 +570,140 @@ sub new {
|
||||||
#-------------------------------------------------------------------
|
#-------------------------------------------------------------------
|
||||||
sub recoverPassword {
|
sub recoverPassword {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
return $self->displayLogin if($self->userId ne "1");
|
return $self->displayLogin unless $self->session->setting->get('webguiPasswordRecovery') and $self->userId eq '1';
|
||||||
my $template = 'Auth/WebGUI/Recovery';
|
my @fields = @{WebGUI::ProfileField->getPasswordRecoveryFields($self->session)};
|
||||||
my $vars;
|
return $self->displayLogin unless @fields;
|
||||||
|
|
||||||
|
my $vars = {};
|
||||||
my $i18n = WebGUI::International->new($self->session);
|
my $i18n = WebGUI::International->new($self->session);
|
||||||
$vars->{title} = $i18n->get(71);
|
$vars->{title} = $i18n->get(71);
|
||||||
$vars->{'recover.form.header'} = "\n\n".WebGUI::Form::formHeader($self->session,{});
|
$vars->{'recoverFormHeader'} = "\n\n".WebGUI::Form::formHeader($self->session,{});
|
||||||
$vars->{'recover.form.hidden'} = WebGUI::Form::hidden($self->session,{"name"=>"op","value"=>"auth"});
|
$vars->{'recoverFormHidden'} = WebGUI::Form::hidden($self->session,{"name"=>"op","value"=>"auth"});
|
||||||
$vars->{'recover.form.hidden'} .= WebGUI::Form::hidden($self->session,{"name"=>"method","value"=>"recoverPasswordFinish"});
|
$vars->{'recoverFormHidden'} .= WebGUI::Form::hidden($self->session,{"name"=>"method","value"=>"recoverPasswordFinish"});
|
||||||
|
|
||||||
$vars->{'recover.form.submit'} = WebGUI::Form::submit($self->session,{});
|
$vars->{'recoverFormSubmit'} = WebGUI::Form::submit($self->session,{});
|
||||||
$vars->{'recover.form.footer'} = WebGUI::Form::formFooter($self->session,);
|
$vars->{'recoverFormFooter'} = WebGUI::Form::formFooter($self->session,);
|
||||||
$vars->{'login.url'} = $self->session->url->page('op=auth;method=init');
|
$vars->{'loginUrl'} = $self->session->url->page('op=auth;method=init');
|
||||||
$vars->{'login.label'} = $i18n->get(58);
|
$vars->{'loginLabel'} = $i18n->get(58);
|
||||||
|
|
||||||
|
$vars->{'anonymousRegistrationIsAllowed'} = ($self->session->setting->get("anonymousRegistration"));
|
||||||
|
$vars->{'createAccountUrl'} = $self->session->url->page('op=auth;method=createAccount');
|
||||||
|
$vars->{'createAccountLabel'} = $i18n->get(67);
|
||||||
|
$vars->{'recoverMessage'} = $_[0] if ($_[0]);
|
||||||
|
|
||||||
|
# Semi-duplication with WebGUI::Auth::createAccount. -.-
|
||||||
|
$vars->{'recoverFormProfile'} = [];
|
||||||
|
foreach my $field (@fields) {
|
||||||
|
my ($id, $formField, $label) = ($field->getId, $field->formField, $field->getLabel);
|
||||||
|
push @{$vars->{'recoverFormProfile'}},
|
||||||
|
+{ 'id' => $id, 'formElement' => $formField, 'label' => $label };
|
||||||
|
|
||||||
|
my $prefix = 'recoverFormProfileField' . ucfirst($id);
|
||||||
|
$vars->{$prefix.'FormElement'} = $formField;
|
||||||
|
$vars->{$prefix.'Label'} = $label;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($self->getSetting('passwordRecoveryRequireUsername')) {
|
||||||
|
$vars->{'recoverFormUsername'} = WebGUI::Form::text($self->session, {name => 'authWebGUI.username'});
|
||||||
|
$vars->{'recoverFormUsernameLabel'} = $i18n->get(50);
|
||||||
|
}
|
||||||
|
|
||||||
$vars->{'anonymousRegistration.isAllowed'} = ($self->session->setting->get("anonymousRegistration"));
|
|
||||||
$vars->{'createAccount.url'} = $self->session->url->page('op=auth;method=createAccount');
|
|
||||||
$vars->{'createAccount.label'} = $i18n->get(67);
|
|
||||||
$vars->{'recover.message'} = $_[0] if ($_[0]);
|
|
||||||
$vars->{'recover.form.email'} = WebGUI::Form::text($self->session,{"name"=>"email"});
|
|
||||||
$vars->{'recover.form.email.label'} = $i18n->get(56);
|
|
||||||
return WebGUI::Asset::Template->new($self->session,$self->getPasswordRecoveryTemplateId)->process($vars);
|
return WebGUI::Asset::Template->new($self->session,$self->getPasswordRecoveryTemplateId)->process($vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
#-------------------------------------------------------------------
|
#-------------------------------------------------------------------
|
||||||
sub recoverPasswordFinish {
|
sub recoverPasswordFinish {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $i18n = WebGUI::International->new($self->session);
|
my $i18n = WebGUI::International->new($self->session);
|
||||||
return $self->recoverPassword('<ul><li>'.$i18n->get(743).'</li></ul>') if ($self->session->form->process("email") eq "");
|
my $i18n2 = WebGUI::International->new($self->session, 'AuthWebGUI');
|
||||||
return $self->displayLogin unless ($self->session->setting->get("webguiPasswordRecovery"));
|
return $self->displayLogin unless $self->session->setting->get('webguiPasswordRecovery') and $self->userId eq '1';
|
||||||
|
|
||||||
my($sth,$username,$userId,$password,$flag,$message,$output,$encryptedPassword,$authMethod);
|
my $username;
|
||||||
$sth = $self->session->db->read("select users.username,users.userId from users, userProfileData where users.userId=userProfileData.userId and
|
if ($self->getSetting('passwordRecoveryRequireUsername')) {
|
||||||
users.authMethod='WebGUI' and userProfileData.fieldName='email' and userProfileData.fieldData=".$self->session->db->quote($self->session->form->process("email")));
|
$username = $self->session->form->process('authWebGUI.username');
|
||||||
$flag = 0;
|
return $self->recoverPassword($i18n2->get('password recovery no username')) unless defined $username;
|
||||||
while (($username,$userId) = $sth->array) {
|
}
|
||||||
my $len = $self->session->setting->get("webguiPasswordLength") || 6;
|
|
||||||
$password = "";
|
my @fields = @{WebGUI::ProfileField->getPasswordRecoveryFields($self->session)};
|
||||||
for(my $i = 0; $i < $len; $i++) {
|
return $self->displayLogin unless @fields;
|
||||||
$password .= chr(ord('A') + randint(32));
|
|
||||||
}
|
my %fieldValues;
|
||||||
$encryptedPassword = Digest::MD5::md5_base64($password);
|
my @failedRequiredFields;
|
||||||
$self->saveParams($userId,"WebGUI",{identifier=>$encryptedPassword});
|
foreach my $field (@fields) {
|
||||||
$self->_logSecurityMessage();
|
my $value = $field->formProcess;
|
||||||
$self->session->errorHandler->security("recover a password. Password emailed to: ".$self->session->form->process("email"));
|
$fieldValues{$field->getId} = $value;
|
||||||
$message = $self->session->setting->get("webguiRecoverPasswordEmail");
|
push @failedRequiredFields, $field unless defined $value;
|
||||||
$message .= "\n".$i18n->get(50).": ".$username."\n";
|
}
|
||||||
$message .= $i18n->get(51).": ".$password."\n";
|
|
||||||
my $mail = WebGUI::Mail::Send->create($self->session, {to=>$self->session->form->process("email"),subject=>$i18n->get(74)});
|
if (@failedRequiredFields) {
|
||||||
$mail->addText($message);
|
my $errorMessage = '<ul>' . join("\n", map {
|
||||||
$mail->addFooter;
|
'<li>' . $_->getLabel . ' ' . $i18n->get(451) . '</li>'
|
||||||
$mail->send;
|
} @failedRequiredFields) . '</ul>';
|
||||||
$flag++;
|
return $self->recoverPassword($errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
my @fieldNames = keys %fieldValues;
|
||||||
|
my @fieldValues = values %fieldValues;
|
||||||
|
my $joins = join(' ', map{"INNER JOIN userProfileData AS p$_ ON u.userId = p$_.userId AND p$_.fieldName = ".$self->session->db->quote($fieldNames[$_])} (0..$#fieldNames));
|
||||||
|
my $wheres = join(' ', map{"AND p$_.fieldData = ?"} (0..$#fieldNames));
|
||||||
|
$wheres .= ' AND u.username = ?' if defined $username;
|
||||||
|
my $sql = "SELECT u.userId FROM users AS u $joins WHERE u.authMethod = 'WebGUI' $wheres";
|
||||||
|
my @userIds = $self->session->db->buildArray($sql, [@fieldValues, (defined($username)? ($username) : ())]);
|
||||||
|
|
||||||
|
if (@userIds == 0) {
|
||||||
|
return $self->recoverPassword($i18n2->get('password recovery no results'));
|
||||||
|
} elsif (@userIds > 1) {
|
||||||
|
return $self->recoverPassword($i18n2->get('password recovery multiple results'));
|
||||||
|
}
|
||||||
|
|
||||||
|
# Exactly one result.
|
||||||
|
my $userId = $userIds[0];
|
||||||
|
my ($password, $passwordConfirm) = ($self->session->form->process('authWebGUI.identifier'), $self->session->form->process('authWebGUI.identifierConfirm'));
|
||||||
|
|
||||||
|
unless (defined $password and defined $passwordConfirm) {
|
||||||
|
my $vars = {};
|
||||||
|
$vars->{title} = $i18n->get(71);
|
||||||
|
$vars->{'recoverFormHeader'} = "\n\n" . WebGUI::Form::formHeader($self->session, {});
|
||||||
|
$vars->{'recoverFormHidden'} =
|
||||||
|
(WebGUI::Form::hidden($self->session, {name => 'op', value => 'auth'})
|
||||||
|
. WebGUI::Form::hidden($self->session, {name => 'method', value => 'recoverPasswordFinish'})
|
||||||
|
. (defined($username)?
|
||||||
|
WebGUI::Form::hidden($self->session, {name => 'authWebGUI.username',
|
||||||
|
value => $username}) : '')
|
||||||
|
. join('', map{WebGUI::Form::hidden($self->session, {name => $_, value => $fieldValues{$_}})}
|
||||||
|
keys %fieldValues));
|
||||||
|
$vars->{'recoverFormSubmit'} = WebGUI::Form::submit($self->session, {});
|
||||||
|
$vars->{'recoverFormFooter'} = WebGUI::Form::formFooter($self->session);
|
||||||
|
|
||||||
|
# Duplication with above in recoverPassword.
|
||||||
|
$vars->{'loginUrl'} = $self->session->url->page('op=auth;method=init');
|
||||||
|
$vars->{'loginLabel'} = $i18n->get(58);
|
||||||
|
|
||||||
|
$vars->{'anonymousRegistrationIsAllowed'} = ($self->session->setting->get("anonymousRegistration"));
|
||||||
|
$vars->{'createAccountUrl'} = $self->session->url->page('op=auth;method=createAccount');
|
||||||
|
$vars->{'createAccountLabel'} = $i18n->get(67);
|
||||||
|
# End duplication.
|
||||||
|
|
||||||
|
$vars->{'recoverFormPassword'} = WebGUI::Form::password($self->session, {name => 'authWebGUI.identifier'});
|
||||||
|
$vars->{'recoverFormPasswordConfirm'} = WebGUI::Form::password($self->session, {name => 'authWebGUI.identifierConfirm'});
|
||||||
|
$vars->{'recoverFormPasswordLabel'} = $i18n->get(51);
|
||||||
|
$vars->{'recoverFormPasswordConfirmLabel'} = $i18n2->get(2);
|
||||||
|
|
||||||
|
# Mrgh. z.z
|
||||||
|
$vars->{'doingRecovery'} = 1;
|
||||||
|
return WebGUI::Asset::Template->new($self->session, $self->getPasswordRecoveryTemplateId)->process($vars);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($self->_isValidPassword($password, $passwordConfirm)) {
|
||||||
|
$self->user(WebGUI::User->new($self->session, $userId));
|
||||||
|
$self->saveParams($userId, $self->authMethod,
|
||||||
|
{ identifier => Digest::MD5::md5_base64($password),
|
||||||
|
passwordLastUpdated => $self->session->datetime->time });
|
||||||
|
$self->_logSecurityMessage;
|
||||||
|
return $self->SUPER::login;
|
||||||
|
} else {
|
||||||
|
return $self->recoverPassword('<ul><li>'.$self->error.'</li></ul>');
|
||||||
}
|
}
|
||||||
$sth->finish();
|
|
||||||
|
|
||||||
return $self->displayLogin('<ul><li>'.$i18n->get(75).'</li></ul>') if($flag);
|
|
||||||
return $self->recoverPassword('<ul><li>'.$i18n->get(76).'</li></ul>');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#-------------------------------------------------------------------
|
#-------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -272,6 +272,12 @@ sub www_editProfileField {
|
||||||
-hoverHelp => $i18n->get('showAtRegistration hoverHelp'),
|
-hoverHelp => $i18n->get('showAtRegistration hoverHelp'),
|
||||||
-value => $data->{showAtRegistration}
|
-value => $data->{showAtRegistration}
|
||||||
);
|
);
|
||||||
|
$f->yesNo(
|
||||||
|
-name => 'requiredForPasswordRecovery',
|
||||||
|
-label => $i18n->get('requiredForPasswordRecovery label'),
|
||||||
|
-hoverHelp => $i18n->get('requiredForPasswordRecovery hoverHelp'),
|
||||||
|
-value => $data->{requiredForPasswordRecovery}
|
||||||
|
);
|
||||||
if ($data->{fieldType} eq "Image") {
|
if ($data->{fieldType} eq "Image") {
|
||||||
$f->yesNo(
|
$f->yesNo(
|
||||||
-name=>"forceImageOnly",
|
-name=>"forceImageOnly",
|
||||||
|
|
@ -343,6 +349,7 @@ sub www_editProfileFieldSave {
|
||||||
visible=>$session->form->yesNo("visible"),
|
visible=>$session->form->yesNo("visible"),
|
||||||
required=>$session->form->yesNo("required"),
|
required=>$session->form->yesNo("required"),
|
||||||
showAtRegistration=>$session->form->yesNo("showAtRegistration"),
|
showAtRegistration=>$session->form->yesNo("showAtRegistration"),
|
||||||
|
requiredForPasswordRecovery=>$session->form->yesNo("requiredForPasswordRecovery"),
|
||||||
possibleValues=>$session->form->textarea("possibleValues"),
|
possibleValues=>$session->form->textarea("possibleValues"),
|
||||||
dataDefault=>$session->form->textarea("dataDefault"),
|
dataDefault=>$session->form->textarea("dataDefault"),
|
||||||
fieldType=>$session->form->fieldType("fieldType"),
|
fieldType=>$session->form->fieldType("fieldType"),
|
||||||
|
|
|
||||||
|
|
@ -343,6 +343,19 @@ sub getRegistrationFields {
|
||||||
return $class->_listFieldsWhere($session, "f.showAtRegistration = 1");
|
return $class->_listFieldsWhere($session, "f.showAtRegistration = 1");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
=head2 getPasswordRecoveryFields ( session )
|
||||||
|
|
||||||
|
Returns an array reference of profile field objects that are required
|
||||||
|
for password recovery. Class method.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub getPasswordRecoveryFields {
|
||||||
|
my $class = shift;
|
||||||
|
my $session = shift;
|
||||||
|
return $class->_listFieldsWhere($session, "f.requiredForPasswordRecovery = 1");
|
||||||
|
}
|
||||||
|
|
||||||
#-------------------------------------------------------------------
|
#-------------------------------------------------------------------
|
||||||
|
|
||||||
=head2 isEditable ( )
|
=head2 isEditable ( )
|
||||||
|
|
|
||||||
|
|
@ -483,6 +483,21 @@ our $I18N = {
|
||||||
lastUpdated => 1128919828,
|
lastUpdated => 1128919828,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'require username for password recovery' => {
|
||||||
|
message => q|Require Username for Password Recovery?|,
|
||||||
|
lastUpdated => 1165402566,
|
||||||
|
},
|
||||||
|
|
||||||
|
'password recovery no results' => {
|
||||||
|
message => q|No users were found matching that profile data. Please try again.|,
|
||||||
|
lastUpdated => 1165402566,
|
||||||
|
},
|
||||||
|
|
||||||
|
'password recovery multiple results' => {
|
||||||
|
message => q|Sorry, password recovery cannot be performed for this account. Please contact an administrator.|,
|
||||||
|
lastUpdated => 1165402566,
|
||||||
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
|
||||||
|
|
@ -351,6 +351,16 @@ new categories of profile settings.
|
||||||
message => "Show an entry for this field at the registration screen for newly-registering users. The field will not actually be required unless Required is also set.",
|
message => "Show an entry for this field at the registration screen for newly-registering users. The field will not actually be required unless Required is also set.",
|
||||||
lastUpdated => 1164237018
|
lastUpdated => 1164237018
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'requiredForPasswordRecovery label' => {
|
||||||
|
message => "Required for password recovery?",
|
||||||
|
lastUpdated => 1165401097
|
||||||
|
},
|
||||||
|
|
||||||
|
'requiredForPasswordRecovery hoverHelp' => {
|
||||||
|
message => "Require users to enter this field for password recovery. Only users that enter all such fields correctly and uniquely to them will be able to perform password recovery.",
|
||||||
|
lastUpdated => 1165401097
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue