Skip to content
This repository was archived by the owner on Aug 30, 2021. It is now read-only.

Commit 1fd6bb6

Browse files
committed
adding stronger password requirements for improving security based on OWASP
1 parent 522cc6b commit 1fd6bb6

20 files changed

+300
-74
lines changed

bower.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
"angular-ui-utils": "bower",
1313
"angular-ui-router": "~0.2",
1414
"angular-file-upload": "1.1.5",
15-
"angular-messages": "1.3.17"
15+
"angular-messages": "1.3.17",
16+
"owasp-password-strength-test": "~1.3.0"
1617
},
1718
"resolutions": {
1819
"angular": "~1.3"

config/assets/default.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ module.exports = {
1515
'public/lib/angular-ui-router/release/angular-ui-router.js',
1616
'public/lib/angular-ui-utils/ui-utils.js',
1717
'public/lib/angular-bootstrap/ui-bootstrap-tpls.js',
18-
'public/lib/angular-file-upload/angular-file-upload.js'
18+
'public/lib/angular-file-upload/angular-file-upload.js',
19+
'public/lib/owasp-password-strength-test/owasp-password-strength-test.js'
1920
],
2021
tests: ['public/lib/angular-mocks/angular-mocks.js']
2122
},

modules/articles/tests/server/article.server.model.tests.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ describe('Article Model Unit Tests:', function () {
2424
displayName: 'Full Name',
2525
2626
username: 'username',
27-
password: 'password'
27+
password: '[email protected]$Aw3$0m3'
2828
});
2929

3030
user.save(function () {

modules/articles/tests/server/article.server.routes.tests.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ describe('Article CRUD tests', function () {
2929
// Create user credentials
3030
credentials = {
3131
username: 'username',
32-
password: 'password'
32+
password: '[email protected]$Aw3$0m3'
3333
};
3434

3535
// Create a new user

modules/users/client/controllers/authentication.client.controller.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
'use strict';
22

3-
angular.module('users').controller('AuthenticationController', ['$scope', '$state', '$http', '$location', '$window', 'Authentication',
4-
function ($scope, $state, $http, $location, $window, Authentication) {
3+
angular.module('users').controller('AuthenticationController', ['$scope', '$state', '$http', '$location', '$window', 'Authentication', 'PasswordValidator',
4+
function ($scope, $state, $http, $location, $window, Authentication, PasswordValidator) {
55
$scope.authentication = Authentication;
6+
$scope.popoverMsg = PasswordValidator.getPopoverMsg();
67

78
// Get an eventual error defined in the URL query string:
89
$scope.error = $location.search().err;

modules/users/client/controllers/password.client.controller.js

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,25 @@
11
'use strict';
22

3-
angular.module('users').controller('PasswordController', ['$scope', '$stateParams', '$http', '$location', 'Authentication',
4-
function ($scope, $stateParams, $http, $location, Authentication) {
3+
angular.module('users').controller('PasswordController', ['$scope', '$stateParams', '$http', '$location', 'Authentication', 'PasswordValidator',
4+
function ($scope, $stateParams, $http, $location, Authentication, PasswordValidator) {
55
$scope.authentication = Authentication;
6+
$scope.popoverMsg = PasswordValidator.getPopoverMsg();
67

78
//If user is signed in then redirect back home
89
if ($scope.authentication.user) {
910
$location.path('/');
1011
}
1112

1213
// Submit forgotten password account id
13-
$scope.askForPasswordReset = function () {
14+
$scope.askForPasswordReset = function (isValid) {
1415
$scope.success = $scope.error = null;
1516

17+
if (!isValid) {
18+
$scope.$broadcast('show-errors-check-validity', 'forgotPasswordForm');
19+
20+
return false;
21+
}
22+
1623
$http.post('/api/auth/forgot', $scope.credentials).success(function (response) {
1724
// Show user success message and clear form
1825
$scope.credentials = null;
@@ -26,9 +33,15 @@ angular.module('users').controller('PasswordController', ['$scope', '$stateParam
2633
};
2734

2835
// Change user password
29-
$scope.resetUserPassword = function () {
36+
$scope.resetUserPassword = function (isValid) {
3037
$scope.success = $scope.error = null;
3138

39+
if (!isValid) {
40+
$scope.$broadcast('show-errors-check-validity', 'resetPasswordForm');
41+
42+
return false;
43+
}
44+
3245
$http.post('/api/auth/reset/' + $stateParams.token, $scope.passwordDetails).success(function (response) {
3346
// If successful show success message and clear form
3447
$scope.passwordDetails = null;

modules/users/client/controllers/settings/change-password.client.controller.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
'use strict';
22

3-
angular.module('users').controller('ChangePasswordController', ['$scope', '$http', 'Authentication',
4-
function ($scope, $http, Authentication) {
3+
angular.module('users').controller('ChangePasswordController', ['$scope', '$http', 'Authentication', 'PasswordValidator',
4+
function ($scope, $http, Authentication, PasswordValidator) {
55
$scope.user = Authentication.user;
6+
$scope.popoverMsg = PasswordValidator.getPopoverMsg();
67

78
// Change user password
89
$scope.changeUserPassword = function (isValid) {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
'use strict';
2+
3+
angular.module('users')
4+
.directive('passwordValidator', ['PasswordValidator', function(PasswordValidator) {
5+
return {
6+
require: 'ngModel',
7+
link: function(scope, element, attrs, modelCtrl) {
8+
modelCtrl.$parsers.unshift(function (password) {
9+
var result = PasswordValidator.getResult(password);
10+
var strengthIdx = 0;
11+
12+
// Strength Meter - visual indicator for users
13+
var strengthMeter = [
14+
{ color: "danger", progress: "20" },
15+
{ color: "warning", progress: "40"},
16+
{ color: "info", progress: "60"},
17+
{ color: "primary", progress: "80"},
18+
{ color: "success", progress: "100"}
19+
];
20+
var strengthMax = strengthMeter.length;
21+
22+
if (result.errors.length < strengthMeter.length) {
23+
strengthIdx = strengthMeter.length - result.errors.length - 1;
24+
}
25+
26+
scope.strengthColor = strengthMeter[strengthIdx].color;
27+
scope.strengthProgress = strengthMeter[strengthIdx].progress;
28+
29+
if (result.errors.length) {
30+
scope.popoverMsg = PasswordValidator.getPopoverMsg();
31+
scope.passwordErrors = result.errors;
32+
modelCtrl.$setValidity('strength', false);
33+
return undefined;
34+
} else {
35+
scope.popoverMsg = '';
36+
modelCtrl.$setValidity('strength', true);
37+
return password;
38+
}
39+
});
40+
}
41+
};
42+
}]);
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
'use strict';
2+
3+
angular.module('users')
4+
.directive("passwordVerify", function() {
5+
return {
6+
require: "ngModel",
7+
scope: {
8+
passwordVerify: '='
9+
},
10+
link: function(scope, element, attrs, modelCtrl) {
11+
scope.$watch(function() {
12+
var combined;
13+
if (scope.passwordVerify || modelCtrl.$viewValue) {
14+
combined = scope.passwordVerify + '_' + modelCtrl.$viewValue;
15+
}
16+
return combined;
17+
}, function(value) {
18+
if (value) {
19+
modelCtrl.$parsers.unshift(function(viewValue) {
20+
var origin = scope.passwordVerify;
21+
if (origin !== viewValue) {
22+
modelCtrl.$setValidity("passwordVerify", false);
23+
return undefined;
24+
} else {
25+
modelCtrl.$setValidity("passwordVerify", true);
26+
return viewValue;
27+
}
28+
});
29+
}
30+
});
31+
}
32+
};
33+
});
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
'use strict';
2+
3+
// PasswordValidator service used for testing the password strength
4+
angular.module('users').factory('PasswordValidator', ['$window',
5+
function ($window) {
6+
var owaspPasswordStrengthTest = $window.owaspPasswordStrengthTest;
7+
8+
return {
9+
getResult: function (password) {
10+
var result = owaspPasswordStrengthTest.test(password);
11+
return result;
12+
},
13+
getPopoverMsg: function () {
14+
var popoverMsg = "Please enter a passphrase or password with greater than 10 characters, numbers, lowercase, upppercase, and special characters.";
15+
return popoverMsg;
16+
}
17+
};
18+
}
19+
]);

0 commit comments

Comments
 (0)