mirror of
https://github.com/nextcloud/passman.git
synced 2025-10-20 02:16:28 +08:00
Style improvements
This commit is contained in:
parent
fc28988da4
commit
adb8e8b087
15 changed files with 394 additions and 61 deletions
59
css/app.css
59
css/app.css
|
@ -1,3 +1,26 @@
|
|||
.actions.creatable {
|
||||
padding-left: 10px; }
|
||||
.actions.creatable .bubble {
|
||||
position: relative;
|
||||
width: 185px;
|
||||
-webkit-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
background-clip: padding-box;
|
||||
/* stops bg color from leaking outside the border: */
|
||||
box-shadow: 0 1px 10px rgba(50, 50, 50, 0.7); }
|
||||
.actions.creatable .bubble ul li {
|
||||
padding-left: 10px; }
|
||||
.actions.creatable .bubble ul .menuitem {
|
||||
font-size: 12px;
|
||||
display: inline; }
|
||||
.actions.creatable .bubble:after {
|
||||
right: inherit;
|
||||
left: 10px;
|
||||
top: -19px; }
|
||||
|
||||
#app-content-wrapper {
|
||||
min-height: 95%; }
|
||||
|
||||
.button-geen {
|
||||
background: #37ce02;
|
||||
color: #fff; }
|
||||
|
@ -14,24 +37,6 @@
|
|||
background: #d83a02;
|
||||
color: #fff; }
|
||||
|
||||
.popovermenu {
|
||||
margin-top: 7px;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
right: -2px !important; }
|
||||
.popovermenu ul {
|
||||
display: block;
|
||||
width: 100px;
|
||||
height: 75px; }
|
||||
.popovermenu ul li {
|
||||
padding: 0px; }
|
||||
.popovermenu ul .menuitem {
|
||||
font-size: 12px;
|
||||
display: inline; }
|
||||
.popovermenu .action {
|
||||
padding: 10px;
|
||||
margin: -10px; }
|
||||
|
||||
.vault_wrapper {
|
||||
margin: 0 auto;
|
||||
margin-top: 20px;
|
||||
|
@ -103,6 +108,24 @@
|
|||
cursor: pointer; }
|
||||
.credential-table tr td .icon-more:hover {
|
||||
opacity: 1; }
|
||||
.credential-table tr td .popovermenu {
|
||||
margin-top: 7px;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
right: -2px !important;
|
||||
box-shadow: 0 1px 10px rgba(50, 50, 50, 0.7); }
|
||||
.credential-table tr td .popovermenu ul {
|
||||
display: block;
|
||||
width: 100px;
|
||||
height: 75px; }
|
||||
.credential-table tr td .popovermenu ul li {
|
||||
padding: 0px; }
|
||||
.credential-table tr td .popovermenu ul .menuitem {
|
||||
font-size: 12px;
|
||||
display: inline; }
|
||||
.credential-table tr td .popovermenu .action {
|
||||
padding: 10px;
|
||||
margin: -10px; }
|
||||
|
||||
.settings-container div {
|
||||
padding-left: 15px; }
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"version": 3,
|
||||
"mappings": "AAAA,YAAY;EACV,UAAU,EAAE,OAAO;EACnB,KAAK,EAAE,IAAI;;AAEb,kBAAkB;EAChB,UAAU,EAAE,OAAoB;EAChC,KAAK,EAAE,IAAI;;AAGb,WAAW;EACT,UAAU,EAAE,OAAO;EACnB,KAAK,EAAE,IAAI;;AAEb,iBAAiB;EACf,UAAU,EAAE,OAAoB;EAChC,KAAK,EAAE,IAAI;;ACfb,YAAa;EACX,UAAU,EAAE,GAAG;EACf,MAAM,EAAE,KAAK;EACb,KAAK,EAAE,KAAK;EACZ,KAAK,EAAE,eAAe;EACtB,eAAG;IACD,OAAO,EAAE,KAAK;IACd,KAAK,EAAE,KAAK;IACZ,MAAM,EAAE,IAAI;IACZ,kBAAE;MACA,OAAO,EAAE,GAAG;IAEd,yBAAS;MACL,SAAS,EAAE,IAAI;MACf,OAAO,EAAE,MAAM;EAGrB,oBAAQ;IACN,OAAO,EAAE,IAAI;IACb,MAAM,EAAE,KAAK;;AClBjB,cAAc;EACZ,MAAM,EAAE,MAAM;EACd,UAAU,EAAE,IAAI;EAChB,KAAK,EAAE,IAAI;EACX,SAAS,EAAE,KAAK;ECMhB,qBAAqB,EDLE,GAAG;ECM1B,aAAa,EDNU,GAAG;ECO1B,eAAe,EAAE,WAAW;EAAG,qDAAqD;EDNpF,UAAU,EAAE,cAAc;EAC1B,UAAU,EAAE,IAAI;EAChB,OAAO,EAAE,KAAK;EACd,yBAAU;IAER,OAAO,EAAE,GAAG;IACZ,4HAAiB;MACf,MAAM,EAAE,OAAO;IAEjB,+BAAK;MACH,KAAK,EAAE,OAAO;IAEhB,qCAAW;MACT,gBAAgB,EAAE,kBAAkB;MACpC,KAAK,EAAE,IAAI;IAEb,4BAAE;MACA,aAAa,EAAE,iBAAiB;MAChC,OAAO,EAAE,IAAI;IAEf,kCAAQ;MACN,gBAAgB,EAAE,OAAO;EAG7B,0BAAW;IACT,OAAO,EAAE,IAAI;IACb,iCAAM;MACJ,KAAK,EAAE,OAAO;IAEhB,gGAA0C;MACxC,KAAK,EAAE,IAAI;MC1Bf,qBAAqB,ED2BM,GAAG;MC1B9B,aAAa,ED0Bc,GAAG;MCzB9B,eAAe,EAAE,WAAW;MAAG,qDAAqD;ID4BhF,kDAAO;MACL,KAAK,EAAE,GAAG;MACV,OAAO,EAAE,YAAY;IAGzB,kCAAO;MACL,UAAU,EAAE,IAAI;;AAKtB,oCAAoC;EAClC,cAAc;IACZ,KAAK,EAAE,GAAG;AEtDd,iBAAiB;EACf,KAAK,EAAE,IAAI;EACX,UAAU,EAAE,IAAI;EAChB,0BAAQ;IACN,gBAAgB,EAAE,UAAgB;EAGlC,uBAAE;IACA,MAAM,EAAE,OAAO;IACf,OAAO,EAAE,GAAG;IACZ,aAAa,EAAE,iBAAiB;IAChC,6BAAK;MACH,KAAK,EAAE,KAAK;MACZ,kCAAI;QACF,gBAAgB,EAAE,wBAAoB;QACtC,OAAO,EAAE,GAAG;QACZ,SAAS,EAAE,IAAI;IAGnB,kCAAU;MACR,OAAO,EAAE,YAAY;MACrB,KAAK,EAAE,KAAK;MACZ,WAAW,EAAE,GAAG;MAChB,UAAU,EAAE,GAAG;MACf,OAAO,EAAE,GAAG;MACZ,MAAM,EAAE,IAAI;MACZ,KAAK,EAAE,IAAI;MACX,MAAM,EAAE,OAAO;IAEjB,wCAAgB;MACd,OAAO,EAAE,CAAC;;AC7BhB,uBAAG;EACD,YAAY,EAAE,IAAI;EAClB,6BAAK;IACH,KAAK,EAAE,kBAA2B;IAClC,MAAM,EAAE,OAAO;EAEjB,mCAAW;IACT,eAAe,EAAE,SAAS;;ACEhC,mCAAoC;EAClC,MAAM,EAAE,IAAI;EACZ,OAAO,EAAE,kBAAkB;EAC3B,OAAO,EAAE,CAAC;EACV,UAAU,EAAE,qBAAqB;;AAEnC,6BAA6B;EAC3B,OAAO,EAAE,kBAAkB;EAC3B,MAAM,EAAE,CAAC;EACT,OAAO,EAAE,CAAC;EACV,UAAU,EAAE,oBAAoB",
|
||||
"sources": ["../sass/partials/button.scss","../sass/partials/popovermenu.scss","../sass/vaults.scss","../sass/mixins.scss","../sass/credentials.scss","../sass/menu.scss","../sass/app.scss"],
|
||||
"mappings": "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",
|
||||
"sources": ["../sass/container.scss","../sass/mixins.scss","../sass/partials/button.scss","../sass/vaults.scss","../sass/credentials.scss","../sass/menu.scss","../sass/app.scss"],
|
||||
"names": [],
|
||||
"file": "app.css"
|
||||
}
|
||||
|
|
45
css/vendor/ng-password-meter/ng-password-meter.css
vendored
Normal file
45
css/vendor/ng-password-meter/ng-password-meter.css
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
.pass-meter {
|
||||
width:100%;
|
||||
padding-top:3px;
|
||||
padding-bottom:4px;
|
||||
}
|
||||
|
||||
.pass-meter.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pass-meter-col {
|
||||
float:left;
|
||||
width:25%;
|
||||
padding:1px;
|
||||
}
|
||||
|
||||
.pass-meter-col .indicator {
|
||||
border-radius:3px;
|
||||
background-color:#eee;
|
||||
height:5px;
|
||||
|
||||
}
|
||||
.pass-meter-col.poor .indicator{
|
||||
background-color:#ef4e3a;
|
||||
}
|
||||
.pass-meter-col.weak .indicator{
|
||||
background-color:#F27B1C;
|
||||
}
|
||||
.pass-meter-col.good .indicator{
|
||||
background-color:#66cc33;
|
||||
}
|
||||
.pass-meter-col.strong .indicator{
|
||||
background-color:#33A7E3;
|
||||
}
|
||||
|
||||
.pass-meter .pass-meter-message {
|
||||
width:100%;
|
||||
text-align:right;
|
||||
font-family: "Arial Black", Gadget, sans-serif;
|
||||
font-size:10px;
|
||||
line-height:10px;
|
||||
font-style:bold;
|
||||
color:#555;
|
||||
min-height:7px;
|
||||
}
|
|
@ -18,7 +18,8 @@ angular
|
|||
'ngTouch',
|
||||
'templates-main',
|
||||
'LocalStorageModule',
|
||||
'offClick'
|
||||
'offClick',
|
||||
'ngPasswordMeter'
|
||||
])
|
||||
.config(function ($routeProvider) {
|
||||
$routeProvider
|
||||
|
|
|
@ -39,6 +39,8 @@ angular.module('passmanApp')
|
|||
_credentials.push(credential);
|
||||
}
|
||||
$scope.credentials = _credentials;
|
||||
|
||||
//@Todo: Set last accessed
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ angular.module('passmanApp')
|
|||
$scope.clearState = function () {
|
||||
$scope.list_selected_vault = false;
|
||||
$scope.creating_vault = false;
|
||||
$scope.error = false;
|
||||
};
|
||||
|
||||
$scope.selectVault = function(vault){
|
||||
|
@ -103,8 +104,8 @@ angular.module('passmanApp')
|
|||
};
|
||||
|
||||
$scope.createVault = function(vault_name, vault_key, vault_key2){
|
||||
if($scope.vaultKey != $scope.vaultKey_2){
|
||||
//@todo Show an message
|
||||
if(vault_key != vault_key2){
|
||||
$scope.error = 'Passwords do not match';
|
||||
return;
|
||||
}
|
||||
VaultService.createVault(vault_name).then(function (vault) {
|
||||
|
|
|
@ -3,11 +3,11 @@ angular.module('templates-main', ['views/show_vault.html', 'views/vaults.html'])
|
|||
angular.module('views/show_vault.html', []).run(['$templateCache', function($templateCache) {
|
||||
'use strict';
|
||||
$templateCache.put('views/show_vault.html',
|
||||
'<div id="controls"><div class="breadcrumb"></div><div class="actions creatable"><span href="#" class="button new"><span class="icon icon-add"></span> <span>New</span></span></div></div><table class="credential-table" ng-init="menuOpen = false"><tr ng-repeat="credential in credentials"><td><span class="label">{{credential.label}}</span> <span class="icon icon-more" ng-click="menuOpen = !menuOpen" off-click="menuOpen = false;"></span> <span class="tags"><span class="tag">Tag 1</span> <span class="tag">Tag 2</span> <span class="tag">Tag 4</span> <span class="tag">Tag 4</span> <span class="tag">Long tag xD</span></span><div class="actionList popovermenu bubble menu" ng-show="menuOpen"><ul><li><span class="menuitem action"><span class="icon icon-rename"></span><span>Edit</span></span></li><li><span href="#" class="menuitem action"><span class="icon icon-share"></span><span>Share</span></span></li><li><span class="menuitem action" data-action="Delete"><span class="icon icon-delete"></span><span>Delete</span></span></li></ul></div></td></tr></table>');
|
||||
'<div id="controls"><div class="breadcrumb"></div><div class="actions creatable"><span ng-click="menuOpen = !menuOpen" class="button new" ng-init="menuOpen = false" off-click="menuOpen = false;"><span>New</span></span><div class="actionList popovermenu bubble menu" ng-show="menuOpen"><ul><li><span class="menuitem action"><span class="icon icon-rename"></span><span>New credential</span></span></li><li><span href="#" class="menuitem action"><span class="icon icon-shared"></span><span>New shared credential</span></span></li></ul></div></div></div><table class="credential-table" ng-init="menuOpen = false"><tr ng-repeat="credential in credentials"><td><span class="label">{{credential.label}}</span> <span class="icon icon-more" ng-click="menuOpen = !menuOpen" off-click="menuOpen = false;"></span> <span class="tags"><span class="tag">Tag 1</span> <span class="tag">Tag 2</span> <span class="tag">Tag 4</span> <span class="tag">Tag 4</span> <span class="tag">Long tag xD</span></span><div class="actionList popovermenu bubble menu" ng-show="menuOpen"><ul><li><span class="menuitem action"><span class="icon icon-rename"></span><span>Edit</span></span></li><li><span href="#" class="menuitem action"><span class="icon icon-share"></span><span>Share</span></span></li><li><span class="menuitem action" data-action="Delete"><span class="icon icon-delete"></span><span>Delete</span></span></li></ul></div></td></tr></table>');
|
||||
}]);
|
||||
|
||||
angular.module('views/vaults.html', []).run(['$templateCache', function($templateCache) {
|
||||
'use strict';
|
||||
$templateCache.put('views/vaults.html',
|
||||
'<div class="vault_wrapper"><div class="vaults" ng-if="!list_selected_vault && !creating_vault"><div class="ui-select-container ui-select-bootstrap vaultlist"><ul><li ng-click="newVault()">+ Create a new vault</li><li ng-repeat="vault in vaults" ng-class="{\'selected\': vault == list_selected_vault }" ng-click="selectVault(vault)"><div><span class="ui-select-choices-row-inner"><div class="ng-binding ng-scope">{{vault.name}}</div><small class="ng-binding ng-scope">Created: {{vault.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}} | Last accessed: <span ng-if="vault.last_access > 0">{{vault.last_access * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</span> <span ng-if="vault.last_access === 0">Never</span></small></span></div></li><li ng-if="vaults.length === 0">No vaults found, why not create one?</li></ul></div></div><div ng-if="creating_vault"><div class="login_form" ng-init="vault_name = \'\' ">Please give your new vault a name.<div><input type="text" ng-model="vault_name"></div><div>Vault password <input type="text" ng-model="vault_key"></div><div>Repeat vault password <input type="text" ng-model="vault_key2"></div><div class="button_wrapper"><div class="button button-geen" ng-click="createVault(vault_name, vault_key, vault_key2)">Create vault</div><div class="button button-red" ng-click="clearState()">Cancel</div></div></div></div><div ng-if="list_selected_vault != false"><div class="vaultlist"><ul><li ng-click="clearState()">Go back to vaults</li></ul></div><div class="login_form"><div ng-show="error" class="error"><ul><li>{{error}}</li></ul></div>Please input the password for {{list_selected_vault.name}}<div><input type="password" ng-model="vault_key"></div><div><div><label><input type="checkbox" ng-checked="default_vault" ng-click="toggleDefaultVault()"> Set this vault as default.</label></div><div><label><input type="checkbox" ng-checked="remember_vault_password" ng-click="toggleRememberPassword()"> Login automatically to this vault.</label></div></div><div class="button button-geen" ng-click="loginToVault(list_selected_vault, vault_key)">Decrypt vault</div></div></div></div>');
|
||||
'<div class="vault_wrapper"><div class="vaults" ng-if="!list_selected_vault && !creating_vault"><div class="ui-select-container ui-select-bootstrap vaultlist"><ul><li ng-click="newVault()">+ Create a new vault</li><li ng-repeat="vault in vaults" ng-class="{\'selected\': vault == list_selected_vault }" ng-click="selectVault(vault)"><div><span class="ui-select-choices-row-inner"><div class="ng-binding ng-scope">{{vault.name}}</div><small class="ng-binding ng-scope">Created: {{vault.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}} | Last accessed: <span ng-if="vault.last_access > 0">{{vault.last_access * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</span> <span ng-if="vault.last_access === 0">Never</span></small></span></div></li><li ng-if="vaults.length === 0">No vaults found, why not create one?</li></ul></div></div><div ng-if="creating_vault"><div class="login_form" ng-init="vault_name = \'\' ">Please give your new vault a name.<div><input type="text" ng-model="vault_name" required></div><div>Vault password <input type="password" ng-model="vault_key" required><ng-password-meter password="vault_key"></ng-password-meter></div><div>Repeat vault password <input type="password" ng-model="vault_key2" required></div><div ng-show="error" class="error"><ul><li>{{error}}</li></ul></div><div class="button_wrapper"><div class="button button-geen" ng-click="createVault(vault_name, vault_key, vault_key2)">Create vault</div><div class="button button-red" ng-click="clearState()">Cancel</div></div></div></div><div ng-if="list_selected_vault != false"><div class="vaultlist"><ul><li ng-click="clearState()">Go back to vaults</li></ul></div><div class="login_form"><div ng-show="error" class="error"><ul><li>{{error}}</li></ul></div>Please input the password for {{list_selected_vault.name}}<div><input type="password" ng-model="vault_key"></div><div><div><label><input type="checkbox" ng-checked="default_vault" ng-click="toggleDefaultVault()"> Set this vault as default.</label></div><div><label><input type="checkbox" ng-checked="remember_vault_password" ng-click="toggleRememberPassword()"> Login automatically to this vault.</label></div></div><div class="button button-geen" ng-click="loginToVault(list_selected_vault, vault_key)">Decrypt vault</div></div></div></div>');
|
||||
}]);
|
||||
|
|
211
js/vendor/ng-password-meter/ng-password-meter.js
vendored
Normal file
211
js/vendor/ng-password-meter/ng-password-meter.js
vendored
Normal file
|
@ -0,0 +1,211 @@
|
|||
(function() {
|
||||
'use strict';
|
||||
|
||||
/* global _ */
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name ngPasswordMeter.directive:ngPassworMeter
|
||||
* @description
|
||||
* Simple and elegant password strength meter from the Lifekees
|
||||
* Password Manager
|
||||
*/
|
||||
angular.module('ngPasswordMeter', [])
|
||||
.directive('ngPasswordMeter', function() {
|
||||
return {
|
||||
template: '<div class="pass-meter {{masterClass}}"><div class="{{colClass}} pass-meter-col {{first}}"><div class="indicator"></div></div><div class="{{colClass}} pass-meter-col {{second}}"><div class="indicator"></div></div><div class="{{colClass}} pass-meter-col {{third}}"><div class="indicator"></div></div><div class="{{colClass}} pass-meter-col {{fourth}}"><div class="indicator"></div></div><div class="pass-meter-message">{{message}}</div></div>',
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
password: '=',
|
||||
strength: '=?',
|
||||
},
|
||||
link: function(scope) {
|
||||
var measureStrength = function(p) {
|
||||
var stringReverse = function(str) {
|
||||
for (var i = str.length - 1, out = ''; i >= 0; out += str[i--]) {}
|
||||
return out;
|
||||
},
|
||||
matches = {
|
||||
pos: {},
|
||||
neg: {}
|
||||
},
|
||||
counts = {
|
||||
pos: {},
|
||||
neg: {
|
||||
seqLetter: 0,
|
||||
seqNumber: 0,
|
||||
seqSymbol: 0
|
||||
}
|
||||
},
|
||||
tmp,
|
||||
strength = 0,
|
||||
letters = 'abcdefghijklmnopqrstuvwxyz',
|
||||
numbers = '01234567890',
|
||||
symbols = '\\!@#$%&/()=?¿',
|
||||
back,
|
||||
forth,
|
||||
i;
|
||||
|
||||
if (p) {
|
||||
// Benefits
|
||||
matches.pos.lower = p.match(/[a-z]/g);
|
||||
matches.pos.upper = p.match(/[A-Z]/g);
|
||||
matches.pos.numbers = p.match(/\d/g);
|
||||
matches.pos.symbols = p.match(/[$-/:-?{-~!^_`\[\]]/g);
|
||||
matches.pos.middleNumber = p.slice(1, -1).match(/\d/g);
|
||||
matches.pos.middleSymbol = p.slice(1, -1).match(/[$-/:-?{-~!^_`\[\]]/g);
|
||||
|
||||
counts.pos.lower = matches.pos.lower ? matches.pos.lower.length : 0;
|
||||
counts.pos.upper = matches.pos.upper ? matches.pos.upper.length : 0;
|
||||
counts.pos.numbers = matches.pos.numbers ? matches.pos.numbers.length : 0;
|
||||
counts.pos.symbols = matches.pos.symbols ? matches.pos.symbols.length : 0;
|
||||
|
||||
tmp = Object.keys(counts.pos).reduce(
|
||||
function(previous, key) {
|
||||
return previous + Math.min(1, counts.pos[key]);
|
||||
},
|
||||
0);
|
||||
|
||||
counts.pos.numChars = p.length;
|
||||
tmp += (counts.pos.numChars >= 8) ? 1 : 0;
|
||||
|
||||
counts.pos.requirements = (tmp >= 3) ? tmp : 0;
|
||||
counts.pos.middleNumber = matches.pos.middleNumber ? matches.pos.middleNumber.length : 0;
|
||||
counts.pos.middleSymbol = matches.pos.middleSymbol ? matches.pos.middleSymbol.length : 0;
|
||||
|
||||
// Deductions
|
||||
matches.neg.consecLower = p.match(/(?=([a-z]{2}))/g);
|
||||
matches.neg.consecUpper = p.match(/(?=([A-Z]{2}))/g);
|
||||
matches.neg.consecNumbers = p.match(/(?=(\d{2}))/g);
|
||||
matches.neg.onlyNumbers = p.match(/^[0-9]*$/g);
|
||||
matches.neg.onlyLetters = p.match(/^([a-z]|[A-Z])*$/g);
|
||||
|
||||
counts.neg.consecLower = matches.neg.consecLower ? matches.neg.consecLower.length : 0;
|
||||
counts.neg.consecUpper = matches.neg.consecUpper ? matches.neg.consecUpper.length : 0;
|
||||
counts.neg.consecNumbers = matches.neg.consecNumbers ? matches.neg.consecNumbers.length : 0;
|
||||
|
||||
|
||||
// sequential letters (back and forth)
|
||||
for (i = 0; i < letters.length - 2; i++) {
|
||||
var p2 = p.toLowerCase();
|
||||
forth = letters.substring(i, parseInt(i + 3));
|
||||
back = stringReverse(forth);
|
||||
if (p2.indexOf(forth) !== -1 || p2.indexOf(back) !== -1) {
|
||||
counts.neg.seqLetter++;
|
||||
}
|
||||
}
|
||||
|
||||
// sequential numbers (back and forth)
|
||||
for (i = 0; i < numbers.length - 2; i++) {
|
||||
forth = numbers.substring(i, parseInt(i + 3));
|
||||
back = stringReverse(forth);
|
||||
if (p.indexOf(forth) !== -1 || p.toLowerCase().indexOf(back) !== -1) {
|
||||
counts.neg.seqNumber++;
|
||||
}
|
||||
}
|
||||
|
||||
// sequential symbols (back and forth)
|
||||
for (i = 0; i < symbols.length - 2; i++) {
|
||||
forth = symbols.substring(i, parseInt(i + 3));
|
||||
back = stringReverse(forth);
|
||||
if (p.indexOf(forth) !== -1 || p.toLowerCase().indexOf(back) !== -1) {
|
||||
counts.neg.seqSymbol++;
|
||||
}
|
||||
}
|
||||
|
||||
// repeated chars
|
||||
var repeats = {};
|
||||
var _p = p.toLowerCase();
|
||||
var arr = _p.split('');
|
||||
counts.neg.repeated = 0;
|
||||
for(i = 0; i< arr.length; i++) {
|
||||
var cnt = 0, idx = 0;
|
||||
while (1) {
|
||||
var idx = _p.indexOf(arr[i], idx);
|
||||
if (idx == -1) break;
|
||||
idx++;
|
||||
cnt++;
|
||||
}
|
||||
if (cnt > 1 && !repeats[_p[i]]) {
|
||||
repeats[_p[i]] = cnt;
|
||||
counts.neg.repeated += cnt;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculations
|
||||
strength += counts.pos.numChars * 4;
|
||||
if (counts.pos.upper) {
|
||||
strength += (counts.pos.numChars - counts.pos.upper) * 2;
|
||||
}
|
||||
if (counts.pos.lower) {
|
||||
strength += (counts.pos.numChars - counts.pos.lower) * 2;
|
||||
}
|
||||
if (counts.pos.upper || counts.pos.lower) {
|
||||
strength += counts.pos.numbers * 4;
|
||||
}
|
||||
strength += counts.pos.symbols * 6;
|
||||
strength += (counts.pos.middleSymbol + counts.pos.middleNumber) * 2;
|
||||
strength += counts.pos.requirements * 2;
|
||||
|
||||
strength -= counts.neg.consecLower * 2;
|
||||
strength -= counts.neg.consecUpper * 2;
|
||||
strength -= counts.neg.consecNumbers * 2;
|
||||
strength -= counts.neg.seqNumber * 3;
|
||||
strength -= counts.neg.seqLetter * 3;
|
||||
strength -= counts.neg.seqSymbol * 3;
|
||||
|
||||
if (matches.neg.onlyNumbers) {
|
||||
strength -= counts.pos.numChars;
|
||||
}
|
||||
if (matches.neg.onlyLetters) {
|
||||
strength -= counts.pos.numChars;
|
||||
}
|
||||
if (counts.neg.repeated) {
|
||||
strength -= (counts.neg.repeated / counts.pos.numChars) * 10;
|
||||
}
|
||||
}
|
||||
return Math.max(0, Math.min(100, Math.round(strength)));
|
||||
};
|
||||
|
||||
scope.colClass = '';
|
||||
scope.masterClass = '';
|
||||
|
||||
scope.$watch('password', function() {
|
||||
scope.first = '';
|
||||
scope.second = '';
|
||||
scope.third = '';
|
||||
scope.fourth = '';
|
||||
scope.message = '';
|
||||
|
||||
if (!scope.password) {
|
||||
scope.masterClass = 'hidden';
|
||||
return;
|
||||
}
|
||||
scope.strength = measureStrength(scope.password);
|
||||
scope.masterClass = '';
|
||||
|
||||
if (scope.strength < 25) {
|
||||
scope.first = 'poor';
|
||||
scope.message = 'Poor';
|
||||
} else if (scope.strength < 50) {
|
||||
scope.first = 'weak';
|
||||
scope.second = 'weak';
|
||||
scope.message = 'weak';
|
||||
} else if (scope.strength < 75) {
|
||||
scope.first = 'good';
|
||||
scope.second = 'good';
|
||||
scope.third = 'good';
|
||||
scope.message = 'good';
|
||||
} else if (scope.strength <= 100) {
|
||||
scope.first = 'strong';
|
||||
scope.second = 'strong';
|
||||
scope.third = 'strong';
|
||||
scope.fourth = 'strong';
|
||||
scope.message = 'strong';
|
||||
}
|
||||
|
||||
});
|
||||
},
|
||||
};
|
||||
});
|
||||
})();
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
@import 'container';
|
||||
@import 'variables';
|
||||
@import 'mixins';
|
||||
@import 'container';
|
||||
@import 'partials/button';
|
||||
@import 'partials/popovermenu';
|
||||
@import 'vaults';
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
.actions.creatable{
|
||||
padding-left: 10px;
|
||||
.bubble{
|
||||
position: relative;
|
||||
width: 185px;
|
||||
@include border-radius(5px);
|
||||
box-shadow: 0 1px 10px rgba(50, 50, 50, .7);
|
||||
ul{
|
||||
li{
|
||||
padding-left: 10px;
|
||||
}
|
||||
.menuitem{
|
||||
font-size: 12px;
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
}
|
||||
.bubble:after{
|
||||
right: inherit;
|
||||
left: 10px;
|
||||
top: -19px;
|
||||
}
|
||||
}
|
||||
#app-content-wrapper{
|
||||
min-height: 95%;
|
||||
}
|
|
@ -30,6 +30,29 @@
|
|||
.icon-more:hover{
|
||||
opacity: 1;
|
||||
}
|
||||
.popovermenu {
|
||||
margin-top: 7px;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
right: -2px !important;
|
||||
box-shadow: 0 1px 10px rgba(50, 50, 50, .7);
|
||||
ul {
|
||||
display: block;
|
||||
width: 100px;
|
||||
height: 75px;
|
||||
li{
|
||||
padding: 0px;
|
||||
}
|
||||
.menuitem{
|
||||
font-size: 12px;
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
.action {
|
||||
padding: 10px;
|
||||
margin: -10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
.popovermenu {
|
||||
margin-top: 7px;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
right: -2px !important;
|
||||
ul {
|
||||
display: block;
|
||||
width: 100px;
|
||||
height: 75px;
|
||||
li{
|
||||
padding: 0px;
|
||||
}
|
||||
.menuitem{
|
||||
font-size: 12px;
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
.action {
|
||||
padding: 10px;
|
||||
margin: -10px;
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ script('passman', 'vendor/angular-sanitize/angular-sanitize.min');
|
|||
script('passman', 'vendor/angular-touch/angular-touch.min');
|
||||
script('passman', 'vendor/angular-local-storage/angular-local-storage.min');
|
||||
script('passman', 'vendor/angular-off-click/angular-off-click.min');
|
||||
script('passman', 'vendor/ng-password-meter/ng-password-meter');
|
||||
script('passman', 'vendor/sjcl/sjcl');
|
||||
|
||||
|
||||
|
@ -32,6 +33,7 @@ script('passman', 'app/services/encryptservice');
|
|||
* Styles
|
||||
*/
|
||||
style('passman', 'app');
|
||||
style('passman', 'vendor/ng-password-meter/ng-password-meter');
|
||||
?>
|
||||
|
||||
<div id="app" ng-app="passmanApp" ng-controller="MainCtrl">
|
||||
|
|
|
@ -7,16 +7,31 @@
|
|||
<!--</div>-->
|
||||
</div>
|
||||
<div class="actions creatable">
|
||||
<span href="#" class="button new">
|
||||
<span class="icon icon-add"></span>
|
||||
<span>New</span></span>
|
||||
<span ng-click="menuOpen = !menuOpen" class="button new" ng-init="menuOpen = false" off-click="menuOpen = false;">
|
||||
<span
|
||||
>New</span></span>
|
||||
<div class="actionList popovermenu bubble menu" ng-show="menuOpen">
|
||||
<ul>
|
||||
<li><span
|
||||
class="menuitem action"
|
||||
><span
|
||||
class="icon icon-rename"></span><span>New credential</span></span>
|
||||
</li>
|
||||
<li><span href="#"
|
||||
class="menuitem action"
|
||||
><span
|
||||
class="icon icon-shared"></span><span>New shared credential</span></span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<table class="credential-table" ng-init="menuOpen = false">
|
||||
<tr ng-repeat="credential in credentials">
|
||||
<td>
|
||||
<span class="label">{{credential.label}}</span>
|
||||
<span class="icon icon-more" ng-click="menuOpen = !menuOpen" off-click="menuOpen = false;"></span>
|
||||
<span class="icon icon-more" ng-click="menuOpen = !menuOpen"
|
||||
off-click="menuOpen = false;"></span>
|
||||
<span class="tags">
|
||||
<span class="tag">Tag 1</span>
|
||||
<span class="tag">Tag 2</span>
|
||||
|
@ -27,18 +42,18 @@
|
|||
<div class="actionList popovermenu bubble menu" ng-show="menuOpen">
|
||||
<ul>
|
||||
<li><span
|
||||
class="menuitem action"
|
||||
><span
|
||||
class="menuitem action"
|
||||
><span
|
||||
class="icon icon-rename"></span><span>Edit</span></span>
|
||||
</li>
|
||||
<li><span href="#"
|
||||
class="menuitem action"
|
||||
><span
|
||||
class="menuitem action"
|
||||
><span
|
||||
class="icon icon-share"></span><span>Share</span></span>
|
||||
</li>
|
||||
<li><span
|
||||
class="menuitem action"
|
||||
data-action="Delete"><span
|
||||
class="menuitem action"
|
||||
data-action="Delete"><span
|
||||
class="icon icon-delete"></span><span>Delete</span></span>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
@ -30,15 +30,21 @@
|
|||
<div class="login_form" ng-init="vault_name = '' ">
|
||||
Please give your new vault a name.
|
||||
<div>
|
||||
<input type="text" ng-model="vault_name">
|
||||
<input type="text" ng-model="vault_name" required>
|
||||
</div>
|
||||
<div>
|
||||
Vault password
|
||||
<input type="text" ng-model="vault_key">
|
||||
<input type="password" ng-model="vault_key" required>
|
||||
<ng-password-meter password="vault_key"></ng-password-meter>
|
||||
</div>
|
||||
<div>
|
||||
Repeat vault password
|
||||
<input type="text" ng-model="vault_key2">
|
||||
<input type="password" ng-model="vault_key2" required>
|
||||
</div>
|
||||
<div ng-show="error" class="error">
|
||||
<ul>
|
||||
<li>{{error}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="button_wrapper">
|
||||
<div class="button button-geen" ng-click="createVault(vault_name, vault_key, vault_key2)">
|
||||
|
|
Loading…
Add table
Reference in a new issue