diff --git a/frappe/__init__.py b/frappe/__init__.py
index f789ce0275..f59a4c0be2 100644
--- a/frappe/__init__.py
+++ b/frappe/__init__.py
@@ -13,7 +13,7 @@ import os, sys, importlib, inspect, json
from .exceptions import *
from .utils.jinja import get_jenv, get_template, render_template
-__version__ = '8.0.64'
+__version__ = '8.0.65'
__title__ = "Frappe Framework"
local = Local()
diff --git a/frappe/core/doctype/user/user.py b/frappe/core/doctype/user/user.py
index c2d0b6abb0..94618948e3 100644
--- a/frappe/core/doctype/user/user.py
+++ b/frappe/core/doctype/user/user.py
@@ -49,7 +49,9 @@ class User(Document):
self.__new_password = self.new_password
self.new_password = ""
- self.password_strength_test()
+ if not frappe.flags.in_test:
+ self.password_strength_test()
+
if self.name not in STANDARD_USERS:
self.validate_email_type(self.email)
self.validate_email_type(self.name)
@@ -409,7 +411,8 @@ class User(Document):
self.username = ""
def password_strength_test(self):
- if self.__new_password:
+ """ test password strength """
+ if frappe.db.get_single_value("System Settings", "enable_password_policy") and self.__new_password:
user_data = (self.first_name, self.middle_name, self.last_name, self.email, self.birth_date)
result = test_password_strength(self.__new_password, '', None, user_data)
@@ -869,4 +872,4 @@ def handle_password_test_fail(result):
suggestions = result['feedback']['suggestions'][0] if result['feedback']['suggestions'] else ''
warning = result['feedback']['warning'] if 'warning' in result['feedback'] else ''
suggestions += "
" + _("Hint: Include symbols, numbers and capital letters in the password") + '
'
- frappe.throw(_('Invalid Password: ' + ' '.join([warning, suggestions])))
\ No newline at end of file
+ frappe.throw(_('Invalid Password: ' + ' '.join([warning, suggestions])))
diff --git a/frappe/model/document.py b/frappe/model/document.py
index 4dbfe36b18..c5b5ca08a7 100644
--- a/frappe/model/document.py
+++ b/frappe/model/document.py
@@ -709,6 +709,7 @@ class Document(BaseDocument):
# value change is not applicable in insert
event_map['validate'] = 'Value Change'
event_map['before_change'] = 'Value Change'
+ event_map['before_update_after_submit'] = 'Value Change'
for alert in self.flags.email_alerts:
event = event_map.get(method, None)
diff --git a/frappe/public/js/frappe/form/multi_select_dialog.js b/frappe/public/js/frappe/form/multi_select_dialog.js
index f61e1021c8..337e209739 100644
--- a/frappe/public/js/frappe/form/multi_select_dialog.js
+++ b/frappe/public/js/frappe/form/multi_select_dialog.js
@@ -23,7 +23,7 @@ frappe.ui.form.MultiSelectDialog = Class.extend({
let fields = [
{
fieldtype: "Data",
- label: __("Search term"),
+ label: __("Search Term"),
fieldname: "search_term"
},
{
diff --git a/frappe/public/js/lib/frappe-gantt/frappe-gantt.js b/frappe/public/js/lib/frappe-gantt/frappe-gantt.js
index ffdba872dd..4796517d5c 100755
--- a/frappe/public/js/lib/frappe-gantt/frappe-gantt.js
+++ b/frappe/public/js/lib/frappe-gantt/frappe-gantt.js
@@ -661,7 +661,9 @@ return /******/ (function(modules) { // webpackBootstrap
);
self.element_groups.arrow.add(arrow.element);
return arrow; // eslint-disable-line
- });
+ }).filter(function (arr) {
+ return arr;
+ }); // filter falsy values
self._arrows = self._arrows.concat(arrows);
};
diff --git a/frappe/utils/password_strength.py b/frappe/utils/password_strength.py
index 215ba1cba0..f94893ed53 100644
--- a/frappe/utils/password_strength.py
+++ b/frappe/utils/password_strength.py
@@ -2,8 +2,10 @@
# MIT License. See license.txt
from __future__ import unicode_literals
-from frappe import _
+
import zxcvbn
+import frappe
+from frappe import _
def test_password_strength(password, user_inputs=None):
'''Wrapper around zxcvbn.password_strength'''
@@ -35,12 +37,14 @@ def get_feedback (score, sequence):
"""
Returns the feedback dictionary consisting of ("warning","suggestions") for the given sequences.
"""
+ minimum_password_score = frappe.db.get_single_value("System Settings", "minimum_password_score")
+
global default_feedback
# Starting feedback
if len(sequence) == 0:
return default_feedback
# No feedback if score is good or great
- if score > 2:
+ if score >= minimum_password_score:
return dict({"warning": "","suggestions": []})
# Tie feedback to the longest match for longer sequences
longest_match = max(sequence, key=lambda x: len(x['token']))
@@ -132,7 +136,9 @@ def get_match_feedback(match, is_sole_match):
"date": fun_date,
"year": fun_date
}
- return(patterns[match['pattern']]())
+ pattern_fn = patterns.get(match['pattern'])
+ if pattern_fn:
+ return(pattern_fn())
def get_dictionary_match_feedback(match, is_sole_match):
"""