1
0
mirror of https://github.com/bitwarden/browser synced 2026-01-04 09:33:27 +00:00

reorganize project folder structure and remove asp.net dependency

This commit is contained in:
Kyle Spearrin
2016-11-30 23:50:00 -05:00
parent a5b8e703fc
commit b72a52232d
94 changed files with 76 additions and 330 deletions

View File

@@ -0,0 +1,30 @@
angular
.module('bit.directives')
.directive('apiField', function () {
var linkFn = function (scope, element, attrs, ngModel) {
ngModel.$registerApiError = registerApiError;
ngModel.$validators.apiValidate = apiValidator;
function apiValidator() {
ngModel.$setValidity('api', true);
return true;
}
function registerApiError() {
ngModel.$setValidity('api', false);
}
};
return {
require: 'ngModel',
restrict: 'A',
compile: function (elem, attrs) {
if (!attrs.name || attrs.name === '') {
throw 'api-field element does not have a valid name attribute';
}
return linkFn;
}
};
});

View File

@@ -0,0 +1,35 @@
angular
.module('bit.directives')
.directive('apiForm', function ($rootScope, validationService) {
return {
require: 'form',
restrict: 'A',
link: function (scope, element, attrs, formCtrl) {
var watchPromise = attrs.apiForm || null;
if (watchPromise !== void 0) {
scope.$watch(watchPromise, formSubmitted.bind(null, formCtrl, scope));
}
}
};
function formSubmitted(form, scope, promise) {
if (!promise || !promise.then) {
return;
}
// reset errors
form.$errors = null;
// start loading
form.$loading = true;
promise.then(function success(response) {
form.$loading = false;
}, function failure(reason) {
form.$loading = false;
validationService.addErrors(form, reason);
scope.$broadcast('show-errors-check-validity');
});
}
});

View File

@@ -0,0 +1,2 @@
angular
.module('bit.directives', []);

View File

@@ -0,0 +1,40 @@
angular
.module('bit.directives')
.directive('masterPassword', function (cryptoService, authService) {
return {
require: 'ngModel',
restrict: 'A',
link: function (scope, elem, attr, ngModel) {
var profile = authService.getUserProfile();
if (!profile) {
return;
}
// For DOM -> model validation
ngModel.$parsers.unshift(function (value) {
if (!value) {
return undefined;
}
var key = cryptoService.makeKey(value, profile.email, true);
var valid = key === cryptoService.getKey(true);
ngModel.$setValidity('masterPassword', valid);
return valid ? value : undefined;
});
// For model -> DOM validation
ngModel.$formatters.unshift(function (value) {
if (!value) {
return undefined;
}
var key = cryptoService.makeKey(value, profile.email, true);
var valid = key === cryptoService.getKey(true);
ngModel.$setValidity('masterPassword', valid);
return value;
});
}
};
});

View File

@@ -0,0 +1,22 @@
angular
.module('bit.directives')
.directive('pageTitle', function ($rootScope, $timeout, appSettings) {
return {
link: function (scope, element) {
var listener = function (event, toState, toParams, fromState, fromParams) {
// Default title
var title = 'bitwarden Password Manager';
if (toState.data && toState.data.pageTitle) {
title = toState.data.pageTitle + ' - bitwarden Password Manager';
}
$timeout(function () {
element.text(title);
});
};
$rootScope.$on('$stateChangeStart', listener);
}
};
});

View File

@@ -0,0 +1,73 @@
angular
.module('bit.directives')
.directive('passwordMeter', function () {
return {
template: '<div class="progress {{outerClass}}"><div class="progress-bar progress-bar-{{valueClass}}" ' +
'role="progressbar" aria-valuenow="{{value}}" aria-valuemin="0" aria-valuemax="100" ' +
'ng-style="{width : ( value + \'%\' ) }"><span class="sr-only">{{value}}%</span></div></div>',
restrict: 'A',
scope: {
password: '=passwordMeter',
username: '=passwordMeterUsername',
outerClass: '@?'
},
link: function (scope) {
var measureStrength = function (username, password) {
if (!password || password === username) {
return 0;
}
var strength = password.length;
if (username && username !== '') {
if (username.indexOf(password) !== -1) strength -= 15;
if (password.indexOf(username) !== -1) strength -= username.length;
}
if (password.length > 0 && password.length <= 4) strength += password.length;
else if (password.length >= 5 && password.length <= 7) strength += 6;
else if (password.length >= 8 && password.length <= 15) strength += 12;
else if (password.length >= 16) strength += 18;
if (password.match(/[a-z]/)) strength += 1;
if (password.match(/[A-Z]/)) strength += 5;
if (password.match(/\d/)) strength += 5;
if (password.match(/.*\d.*\d.*\d/)) strength += 5;
if (password.match(/[!,@,#,$,%,^,&,*,?,_,~]/)) strength += 5;
if (password.match(/.*[!,@,#,$,%,^,&,*,?,_,~].*[!,@,#,$,%,^,&,*,?,_,~]/)) strength += 5;
if (password.match(/(?=.*[a-z])(?=.*[A-Z])/)) strength += 2;
if (password.match(/(?=.*\d)(?=.*[a-z])(?=.*[A-Z])/)) strength += 2;
if (password.match(/(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!,@,#,$,%,^,&,*,?,_,~])/)) strength += 2;
strength = Math.round(strength * 2);
return Math.max(0, Math.min(100, strength));
};
var getClass = function (strength) {
switch (Math.round(strength / 33)) {
case 0:
case 1:
return 'danger';
case 2:
return 'warning';
case 3:
return 'success';
}
};
var updateMeter = function (scope) {
scope.value = measureStrength(scope.username, scope.password);
scope.valueClass = getClass(scope.value);
};
scope.$watch('password', function () {
updateMeter(scope);
});
scope.$watch('username', function () {
updateMeter(scope);
});
},
};
});

View File

@@ -0,0 +1,27 @@
angular
.module('bit.directives')
.directive('passwordViewer', function () {
return {
restrict: 'A',
link: function (scope, element, attr) {
var passwordViewer = attr.passwordViewer;
if (!passwordViewer) {
return;
}
element.onclick = function (event) { };
element.on('click', function (event) {
var passwordElement = $(passwordViewer);
if (passwordElement && passwordElement.attr('type') === 'password') {
element.removeClass('fa-eye').addClass('fa-eye-slash');
passwordElement.attr('type', 'text');
}
else if (passwordElement && passwordElement.attr('type') === 'text') {
element.removeClass('fa-eye-slash').addClass('fa-eye');
passwordElement.attr('type', 'password');
}
});
}
};
});