<event code='7026' textcode='PATRON_NOT_AN_ACTIVE_PASSWORD_RESET_REQUEST'>
<desc xml:lang='en-US'>The user attempted to update their password using a stale or inactive password reset request session.</desc>
</event>
+ <event code='7027' textcode='PATRON_PASSWORD_WAS_NOT_STRONG'>
+ <desc xml:lang='en-US'>The user attempted to set their password to a weak value.</desc>
+ </event>
<!-- ================================================================ -->
use OpenILS::Utils::Penalty;
use UUID::Tiny qw/:std/;
+use JavaScript::SpiderMonkey;
sub initialize {
OpenILS::Application::Actor::Container->initialize();
return OpenILS::Event->new('PATRON_NOT_AN_ACTIVE_PASSWORD_RESET_REQUEST');
}
- # TODO Check complexity of password against OU-defined regex
+ # Check complexity of password against OU-defined regex
+ my $pw_regex = $U->ou_ancestor_setting_value($user->home_ou, 'global.password_regex');
+
+ my $is_strong = 'false';
+ if (!$pw_regex) {
+ # Use the default set of checks
+ if ((length($password) < 7)
+ or ($password !~ m/.*\d+.*/)
+ or ($password !~ m/.*[A-Za-z]+.*/)) {
+ # Still false!
+ } else {
+ $is_strong = 'true';
+ }
+ } else {
+ # The password regex is for JavaScript, so we have to use SpiderMonkey to eval it
+ my $js = JavaScript::SpiderMonkey->new();
+ $js->init();
+ $js->property_by_path('pw.is_strong', 'false');
+ $js->property_by_path('pw.password', $password);
+ $js->property_by_path('pw.regex', $pw_regex || 'blank');
+
+ my $pw_script = << 'PWCHECK';
+ if (pw.regex != 'blank') {
+ if (pw.password.match(new RegExp(pwregex))) {
+ pw.is_strong = 'true';
+ }
+ } else {
+ } while(0);
+ }
+PWCHECK
+
+ my $rc = $js->eval($pw_script);
+ if (!$rc) {
+ $logger->error("Error interpreting JavaScript while checking password strength: %s", $@);
+ }
+
+ # Get the value of a property set in JS
+ $is_strong = $js->property_get('pw.is_strong');
+ $js->destroy();
+ }
+
+ if ($is_strong eq 'false') {
+ $e->die_event;
+ return OpenILS::Event->new('PATRON_PASSWORD_WAS_NOT_STRONG');
+ }
# All is well; update the password
$user->passwd($password);
if ($password_1 and $password_2 and ($password_1 eq $password_2)) {
my $response = $actor->request('open-ils.actor.patron.password_reset.commit', $uuid, $password_1)->gather();
- if (ref($response) &&
- $response->{'textcode'} &&
- $response->{'textcode'} eq 'PATRON_NOT_AN_ACTIVE_PASSWORD_RESET_REQUEST') {
+ if (ref($response) && $response->{'textcode'}) {
$apache->status(Apache2::Const::DECLINED);
- $ctx->{'status'} = {
- style => 'error',
- msg => $ctx->{'i18n'}{'NOT_ACTIVE'}
- };
+ if ($response->{'textcode'} eq 'PATRON_NOT_AN_ACTIVE_PASSWORD_RESET_REQUEST') {
+ $ctx->{'status'} = {
+ style => 'error',
+ msg => $ctx->{'i18n'}{'NOT_ACTIVE'}
+
+ };
+ }
+ if ($response->{'textcode'} eq 'PATRON_PASSWORD_WAS_NOT_STRONG') {
+ $ctx->{'status'} = {
+ style => 'error',
+ msg => $ctx->{'i18n'}{'NOT_STRONG'}
+
+ };
+ }
$tt->process('password-reset/reset-form.tt2', $ctx)
|| die $tt->error();
return Apache2::Const::OK;
NO_SESSION=Could not find the requested password reset session.
NO_MATCH=Passwords did not match. Please try again
NOT_ACTIVE=This was not an active password reset request. Your password has not been reset.
+NOT_STRONG=The password you chose was not considered complex enough to protect your account. Your password has not been reset.
SUCCESS=Password has been reset.
TITLE=Library system password reset
PASSWORD_PROMPT=New password: