refactored naming Site => Login

This commit is contained in:
Kyle Spearrin 2017-01-02 22:26:32 -05:00
parent e01a22de48
commit f7fd28fded
16 changed files with 516 additions and 516 deletions

View File

@ -40,8 +40,8 @@ angular
$state.go('backend.vault'); $state.go('backend.vault');
}; };
$scope.addSite = function () { $scope.addLogin = function () {
$scope.$broadcast('vaultAddSite'); $scope.$broadcast('vaultAddLogin');
}; };
$scope.addFolder = function () { $scope.addFolder = function () {

View File

@ -5,12 +5,12 @@
var _service = {}, var _service = {},
_apiUri = appSettings.apiUri; _apiUri = appSettings.apiUri;
_service.sites = $resource(_apiUri + '/sites/:id', {}, { _service.logins = $resource(_apiUri + '/logins/:id', {}, {
get: { method: 'GET', params: { id: '@id' } }, get: { method: 'GET', params: { id: '@id' } },
list: { method: 'GET', params: {} }, list: { method: 'GET', params: {} },
post: { method: 'POST', params: {} }, post: { method: 'POST', params: {} },
put: { method: 'POST', params: { id: '@id' } }, put: { method: 'POST', params: { id: '@id' } },
del: { url: _apiUri + '/sites/:id/delete', method: 'POST', params: { id: '@id' } } del: { url: _apiUri + '/logins/:id/delete', method: 'POST', params: { id: '@id' } }
}); });
_service.folders = $resource(_apiUri + '/folders/:id', {}, { _service.folders = $resource(_apiUri + '/folders/:id', {}, {

View File

@ -4,39 +4,39 @@ angular
.factory('cipherService', function (cryptoService, apiService) { .factory('cipherService', function (cryptoService, apiService) {
var _service = {}; var _service = {};
_service.decryptSites = function (encryptedSites) { _service.decryptLogins = function (encryptedLogins) {
if (!encryptedSites) throw "encryptedSites is undefined or null"; if (!encryptedLogins) throw "encryptedLogins is undefined or null";
var unencryptedSites = []; var encryptedLogins = [];
for (var i = 0; i < encryptedSites.length; i++) { for (var i = 0; i < encryptedLogins.length; i++) {
unencryptedSites.push(_service.decryptSite(encryptedSites[i])); encryptedLogins.push(_service.decryptLogin(encryptedLogins[i]));
} }
return unencryptedSites; return encryptedLogins;
}; };
_service.decryptSite = function (encryptedSite) { _service.decryptLogin = function (encryptedLogin) {
if (!encryptedSite) throw "encryptedSite is undefined or null"; if (!encryptedLogin) throw "encryptedLogin is undefined or null";
var site = { var login = {
id: encryptedSite.Id, id: encryptedLogin.Id,
'type': 1, 'type': 1,
folderId: encryptedSite.FolderId, folderId: encryptedLogin.FolderId,
favorite: encryptedSite.Favorite, favorite: encryptedLogin.Favorite,
name: cryptoService.decrypt(encryptedSite.Name), name: cryptoService.decrypt(encryptedLogin.Name),
uri: encryptedSite.Uri && encryptedSite.Uri !== '' ? cryptoService.decrypt(encryptedSite.Uri) : null, uri: encryptedLogin.Uri && encryptedLogin.Uri !== '' ? cryptoService.decrypt(encryptedLogin.Uri) : null,
username: encryptedSite.Username && encryptedSite.Username !== '' ? cryptoService.decrypt(encryptedSite.Username) : null, username: encryptedLogin.Username && encryptedLogin.Username !== '' ? cryptoService.decrypt(encryptedLogin.Username) : null,
password: encryptedSite.Password && encryptedSite.Password !== '' ? cryptoService.decrypt(encryptedSite.Password) : null, password: encryptedLogin.Password && encryptedLogin.Password !== '' ? cryptoService.decrypt(encryptedLogin.Password) : null,
notes: encryptedSite.Notes && encryptedSite.Notes !== '' ? cryptoService.decrypt(encryptedSite.Notes) : null notes: encryptedLogin.Notes && encryptedLogin.Notes !== '' ? cryptoService.decrypt(encryptedLogin.Notes) : null
}; };
if (encryptedSite.Folder) { if (encryptedLogin.Folder) {
site.folder = { login.folder = {
name: cryptoService.decrypt(encryptedSite.Folder.Name) name: cryptoService.decrypt(encryptedLogin.Folder.Name)
}; };
} }
return site; return login;
}; };
_service.decryptFolders = function (encryptedFolders) { _service.decryptFolders = function (encryptedFolders) {
@ -60,30 +60,30 @@ angular
}; };
}; };
_service.encryptSites = function (unencryptedSites, key) { _service.encryptLogins = function (unencryptedLogins, key) {
if (!unencryptedSites) throw "unencryptedSites is undefined or null"; if (!unencryptedLogins) throw "unencryptedLogins is undefined or null";
var encryptedSites = []; var encryptedLogins = [];
for (var i = 0; i < unencryptedSites.length; i++) { for (var i = 0; i < unencryptedLogins.length; i++) {
encryptedSites.push(_service.encryptSite(unencryptedSites[i], key)); encryptedLogins.push(_service.encryptLogin(unencryptedLogins[i], key));
} }
return encryptedSites; return encryptedLogins;
}; };
_service.encryptSite = function (unencryptedSite, key) { _service.encryptLogin = function (unencryptedLogin, key) {
if (!unencryptedSite) throw "unencryptedSite is undefined or null"; if (!unencryptedLogin) throw "unencryptedLogin is undefined or null";
return { return {
id: unencryptedSite.id, id: unencryptedLogin.id,
'type': 1, 'type': 1,
folderId: unencryptedSite.folderId === '' ? null : unencryptedSite.folderId, folderId: unencryptedLogin.folderId === '' ? null : unencryptedLogin.folderId,
favorite: unencryptedSite.favorite !== null ? unencryptedSite.favorite : false, favorite: unencryptedLogin.favorite !== null ? unencryptedLogin.favorite : false,
uri: !unencryptedSite.uri || unencryptedSite.uri === '' ? null : cryptoService.encrypt(unencryptedSite.uri, key), uri: !unencryptedLogin.uri || unencryptedLogin.uri === '' ? null : cryptoService.encrypt(unencryptedLogin.uri, key),
name: cryptoService.encrypt(unencryptedSite.name, key), name: cryptoService.encrypt(unencryptedLogin.name, key),
username: !unencryptedSite.username || unencryptedSite.username === '' ? null : cryptoService.encrypt(unencryptedSite.username, key), username: !unencryptedLogin.username || unencryptedLogin.username === '' ? null : cryptoService.encrypt(unencryptedLogin.username, key),
password: !unencryptedSite.password || unencryptedSite.password === '' ? null : cryptoService.encrypt(unencryptedSite.password, key), password: !unencryptedLogin.password || unencryptedLogin.password === '' ? null : cryptoService.encrypt(unencryptedLogin.password, key),
notes: !unencryptedSite.notes || unencryptedSite.notes === '' ? null : cryptoService.encrypt(unencryptedSite.notes, key) notes: !unencryptedLogin.notes || unencryptedLogin.notes === '' ? null : cryptoService.encrypt(unencryptedLogin.notes, key)
}; };
}; };

File diff suppressed because it is too large Load Diff

View File

@ -27,10 +27,10 @@
$scope.confirm = function (model) { $scope.confirm = function (model) {
$scope.processing = true; $scope.processing = true;
var reencryptedSites = []; var reencryptedLogins = [];
var sitesPromise = apiService.sites.list({ dirty: false }, function (encryptedSites) { var loginsPromise = apiService.logins.list({ dirty: false }, function (encryptedLogins) {
var unencryptedSites = cipherService.decryptSites(encryptedSites.Data); var unencryptedLogins = cipherService.decryptLogins(encryptedLogins.Data);
reencryptedSites = cipherService.encryptSites(unencryptedSites, _newKey); reencryptedLogins = cipherService.encryptLogins(unencryptedLogins, _newKey);
}).$promise; }).$promise;
var reencryptedFolders = []; var reencryptedFolders = [];
@ -39,13 +39,13 @@
reencryptedFolders = cipherService.encryptFolders(unencryptedFolders, _newKey); reencryptedFolders = cipherService.encryptFolders(unencryptedFolders, _newKey);
}).$promise; }).$promise;
$q.all([sitesPromise, foldersPromise]).then(function () { $q.all([loginsPromise, foldersPromise]).then(function () {
var request = { var request = {
token: model.token, token: model.token,
newEmail: model.newEmail.toLowerCase(), newEmail: model.newEmail.toLowerCase(),
masterPasswordHash: _masterPasswordHash, masterPasswordHash: _masterPasswordHash,
newMasterPasswordHash: _newMasterPasswordHash, newMasterPasswordHash: _newMasterPasswordHash,
ciphers: reencryptedSites.concat(reencryptedFolders) ciphers: reencryptedLogins.concat(reencryptedFolders)
}; };
$scope.confirmPromise = apiService.accounts.email(request, function () { $scope.confirmPromise = apiService.accounts.email(request, function () {

View File

@ -27,10 +27,10 @@
var profile = authService.getUserProfile(); var profile = authService.getUserProfile();
var newKey = cryptoService.makeKey(model.newMasterPassword, profile.email.toLowerCase()); var newKey = cryptoService.makeKey(model.newMasterPassword, profile.email.toLowerCase());
var reencryptedSites = []; var reencryptedLogins = [];
var sitesPromise = apiService.sites.list({ dirty: false }, function (encryptedSites) { var loginsPromise = apiService.logins.list({ dirty: false }, function (encryptedLogins) {
var unencryptedSites = cipherService.decryptSites(encryptedSites.Data); var unencryptedLogins = cipherService.decryptLogins(encryptedLogins.Data);
reencryptedSites = cipherService.encryptSites(unencryptedSites, newKey); reencryptedLogins = cipherService.encryptLogins(unencryptedLogins, newKey);
}).$promise; }).$promise;
var reencryptedFolders = []; var reencryptedFolders = [];
@ -39,11 +39,11 @@
reencryptedFolders = cipherService.encryptFolders(unencryptedFolders, newKey); reencryptedFolders = cipherService.encryptFolders(unencryptedFolders, newKey);
}).$promise; }).$promise;
$q.all([sitesPromise, foldersPromise]).then(function () { $q.all([loginsPromise, foldersPromise]).then(function () {
var request = { var request = {
masterPasswordHash: cryptoService.hashPassword(model.masterPassword), masterPasswordHash: cryptoService.hashPassword(model.masterPassword),
newMasterPasswordHash: cryptoService.hashPassword(model.newMasterPassword, newKey), newMasterPasswordHash: cryptoService.hashPassword(model.newMasterPassword, newKey),
ciphers: reencryptedSites.concat(reencryptedFolders) ciphers: reencryptedLogins.concat(reencryptedFolders)
}; };
$scope.savePromise = apiService.accounts.putPassword(request, function () { $scope.savePromise = apiService.accounts.putPassword(request, function () {

View File

@ -5,25 +5,25 @@
$analytics.eventTrack('toolsExportController', { category: 'Modal' }); $analytics.eventTrack('toolsExportController', { category: 'Modal' });
$scope.export = function (model) { $scope.export = function (model) {
$scope.startedExport = true; $scope.startedExport = true;
apiService.sites.list({ expand: ['folder'] }, function (sites) { apiService.logins.list({ expand: ['folder'] }, function (logins) {
try { try {
var decSites = cipherService.decryptSites(sites.Data); var decLogins = cipherService.decryptLogins(logins.Data);
var exportSites = []; var exportLogins = [];
for (var i = 0; i < decSites.length; i++) { for (var i = 0; i < decLogins.length; i++) {
var site = { var login = {
name: decSites[i].name, name: decLogins[i].name,
uri: decSites[i].uri, uri: decLogins[i].uri,
username: decSites[i].username, username: decLogins[i].username,
password: decSites[i].password, password: decLogins[i].password,
notes: decSites[i].notes, notes: decLogins[i].notes,
folder: decSites[i].folder ? decSites[i].folder.name : null folder: decLogins[i].folder ? decLogins[i].folder.name : null
}; };
exportSites.push(site); exportLogins.push(login);
} }
var csvString = Papa.unparse(exportSites); var csvString = Papa.unparse(exportLogins);
var csvBlob = new Blob([csvString]); var csvBlob = new Blob([csvString]);
if (window.navigator.msSaveOrOpenBlob) { // IE hack. ref http://msdn.microsoft.com/en-us/library/ie/hh779016.aspx if (window.navigator.msSaveOrOpenBlob) { // IE hack. ref http://msdn.microsoft.com/en-us/library/ie/hh779016.aspx
window.navigator.msSaveBlob(csvBlob, makeFileName()); window.navigator.msSaveBlob(csvBlob, makeFileName());

View File

@ -11,15 +11,15 @@
importService.import(model.source, file, importSuccess, importError); importService.import(model.source, file, importSuccess, importError);
}; };
function importSuccess(folders, sites, folderRelationships) { function importSuccess(folders, logins, folderRelationships) {
if (!folders.length && !sites.length) { if (!folders.length && !logins.length) {
importError('Nothing was imported.'); importError('Nothing was imported.');
return; return;
} }
else if (sites.length) { else if (logins.length) {
var halfway = Math.floor(sites.length / 2); var halfway = Math.floor(logins.length / 2);
var last = sites.length - 1; var last = logins.length - 1;
if (siteIsBadData(sites[0]) && siteIsBadData(sites[halfway]) && siteIsBadData(sites[last])) { if (loginIsBadData(logins[0]) && loginIsBadData(logins[halfway]) && loginIsBadData(logins[last])) {
importError('CSV data is not formatted correctly. Please check your import file and try again.'); importError('CSV data is not formatted correctly. Please check your import file and try again.');
return; return;
} }
@ -27,7 +27,7 @@
apiService.ciphers.import({ apiService.ciphers.import({
folders: cipherService.encryptFolders(folders, cryptoService.getKey()), folders: cipherService.encryptFolders(folders, cryptoService.getKey()),
sites: cipherService.encryptSites(sites, cryptoService.getKey()), logins: cipherService.encryptLogins(logins, cryptoService.getKey()),
folderRelationships: folderRelationships folderRelationships: folderRelationships
}, function () { }, function () {
$uibModalInstance.dismiss('cancel'); $uibModalInstance.dismiss('cancel');
@ -38,8 +38,8 @@
}, importError); }, importError);
} }
function siteIsBadData(site) { function loginIsBadData(login) {
return (site.name === null || site.name === '--') && (site.password === null || site.password === ''); return (login.name === null || login.name === '--') && (login.password === null || login.password === '');
} }
function importError(error) { function importError(error) {

View File

@ -1,27 +1,27 @@
angular angular
.module('bit.vault') .module('bit.vault')
.controller('vaultAddSiteController', function ($scope, apiService, $uibModalInstance, cryptoService, cipherService, passwordService, folders, selectedFolder, $analytics) { .controller('vaultAddLoginController', function ($scope, apiService, $uibModalInstance, cryptoService, cipherService, passwordService, folders, selectedFolder, $analytics) {
$analytics.eventTrack('vaultAddSiteController', { category: 'Modal' }); $analytics.eventTrack('vaultAddLoginController', { category: 'Modal' });
$scope.folders = folders; $scope.folders = folders;
$scope.site = { $scope.login = {
folderId: selectedFolder ? selectedFolder.id : null folderId: selectedFolder ? selectedFolder.id : null
}; };
$scope.savePromise = null; $scope.savePromise = null;
$scope.save = function (model) { $scope.save = function (model) {
var site = cipherService.encryptSite(model); var login = cipherService.encryptLogin(model);
$scope.savePromise = apiService.sites.post(site, function (siteResponse) { $scope.savePromise = apiService.logins.post(login, function (loginResponse) {
$analytics.eventTrack('Created Site'); $analytics.eventTrack('Created Login');
var decSite = cipherService.decryptSite(siteResponse); var decLogin = cipherService.decryptLogin(loginResponse);
$uibModalInstance.close(decSite); $uibModalInstance.close(decLogin);
}).$promise; }).$promise;
}; };
$scope.generatePassword = function () { $scope.generatePassword = function () {
if (!$scope.site.password || confirm('Are you sure you want to overwrite the current password?')) { if (!$scope.login.password || confirm('Are you sure you want to overwrite the current password?')) {
$analytics.eventTrack('Generated Password From Add'); $analytics.eventTrack('Generated Password From Add');
$scope.site.password = passwordService.generatePassword({ length: 10, special: true }); $scope.login.password = passwordService.generatePassword({ length: 10, special: true });
} }
}; };

View File

@ -2,35 +2,35 @@
.module('bit.vault') .module('bit.vault')
.controller('vaultController', function ($scope, $uibModal, apiService, $filter, cryptoService, authService, toastr, cipherService) { .controller('vaultController', function ($scope, $uibModal, apiService, $filter, cryptoService, authService, toastr, cipherService) {
$scope.sites = []; $scope.logins = [];
$scope.folders = []; $scope.folders = [];
$scope.loadingSites = true; $scope.loadingLogins = true;
apiService.sites.list({}, function (sites) { apiService.logins.list({}, function (logins) {
$scope.loadingSites = false; $scope.loadingLogins = false;
var decSites = []; var decLogins = [];
for (var i = 0; i < sites.Data.length; i++) { for (var i = 0; i < logins.Data.length; i++) {
var decSite = { var decLogin = {
id: sites.Data[i].Id, id: logins.Data[i].Id,
folderId: sites.Data[i].FolderId, folderId: logins.Data[i].FolderId,
favorite: sites.Data[i].Favorite favorite: logins.Data[i].Favorite
}; };
try { decSite.name = cryptoService.decrypt(sites.Data[i].Name); } try { decLogin.name = cryptoService.decrypt(logins.Data[i].Name); }
catch (err) { decSite.name = '[error: cannot decrypt]'; } catch (err) { decLogin.name = '[error: cannot decrypt]'; }
if (sites.Data[i].Username) { if (logins.Data[i].Username) {
try { decSite.username = cryptoService.decrypt(sites.Data[i].Username); } try { decLogin.username = cryptoService.decrypt(logins.Data[i].Username); }
catch (err) { decSite.username = '[error: cannot decrypt]'; } catch (err) { decLogin.username = '[error: cannot decrypt]'; }
} }
decSites.push(decSite); decLogins.push(decLogin);
} }
$scope.sites = decSites; $scope.logins = decLogins;
}, function () { }, function () {
$scope.loadingSites = false; $scope.loadingLogins = false;
}); });
$scope.loadingFolders = true; $scope.loadingFolders = true;
@ -66,69 +66,69 @@
return item.name.toLowerCase(); return item.name.toLowerCase();
}; };
$scope.editSite = function (site) { $scope.editLogin = function (login) {
var editModel = $uibModal.open({ var editModel = $uibModal.open({
animation: true, animation: true,
templateUrl: 'app/vault/views/vaultEditSite.html', templateUrl: 'app/vault/views/vaultEditLogin.html',
controller: 'vaultEditSiteController', controller: 'vaultEditLoginController',
resolve: { resolve: {
siteId: function () { return site.id; }, loginId: function () { return login.id; },
folders: function () { return $scope.folders; } folders: function () { return $scope.folders; }
} }
}); });
editModel.result.then(function (returnVal) { editModel.result.then(function (returnVal) {
if (returnVal.action === 'edit') { if (returnVal.action === 'edit') {
var siteToUpdate = $filter('filter')($scope.sites, { id: returnVal.data.id }, true); var loginToUpdate = $filter('filter')($scope.logins, { id: returnVal.data.id }, true);
if (siteToUpdate && siteToUpdate.length > 0) { if (loginToUpdate && loginToUpdate.length > 0) {
siteToUpdate[0].folderId = returnVal.data.folderId; loginToUpdate[0].folderId = returnVal.data.folderId;
siteToUpdate[0].name = returnVal.data.name; loginToUpdate[0].name = returnVal.data.name;
siteToUpdate[0].username = returnVal.data.username; loginToUpdate[0].username = returnVal.data.username;
siteToUpdate[0].favorite = returnVal.data.favorite; loginToUpdate[0].favorite = returnVal.data.favorite;
} }
} }
else if (returnVal.action === 'delete') { else if (returnVal.action === 'delete') {
var siteToDelete = $filter('filter')($scope.sites, { id: returnVal.data }, true); var loginToDelete = $filter('filter')($scope.logins, { id: returnVal.data }, true);
if (siteToDelete && siteToDelete.length > 0) { if (loginToDelete && loginToDelete.length > 0) {
var index = $scope.sites.indexOf(siteToDelete[0]); var index = $scope.logins.indexOf(loginToDelete[0]);
if (index > -1) { if (index > -1) {
$scope.sites.splice(index, 1); $scope.logins.splice(index, 1);
} }
} }
} }
}); });
}; };
$scope.$on('vaultAddSite', function (event, args) { $scope.$on('vaultAddLogin', function (event, args) {
$scope.addSite(); $scope.addLogin();
}); });
$scope.addSite = function (folder) { $scope.addLogin = function (folder) {
var addModel = $uibModal.open({ var addModel = $uibModal.open({
animation: true, animation: true,
templateUrl: 'app/vault/views/vaultAddSite.html', templateUrl: 'app/vault/views/vaultAddLogin.html',
controller: 'vaultAddSiteController', controller: 'vaultAddLoginController',
resolve: { resolve: {
folders: function () { return $scope.folders; }, folders: function () { return $scope.folders; },
selectedFolder: function () { return folder; } selectedFolder: function () { return folder; }
} }
}); });
addModel.result.then(function (addedSite) { addModel.result.then(function (addedLogin) {
$scope.sites.push(addedSite); $scope.logins.push(addedLogin);
}); });
}; };
$scope.deleteSite = function (site) { $scope.deleteLogin = function (login) {
if (!confirm('Are you sure you want to delete this site (' + site.name + ')?')) { if (!confirm('Are you sure you want to delete this login (' + login.name + ')?')) {
return; return;
} }
apiService.sites.del({ id: site.id }, function () { apiService.logins.del({ id: login.id }, function () {
var index = $scope.sites.indexOf(site); var index = $scope.logins.indexOf(login);
if (index > -1) { if (index > -1) {
$scope.sites.splice(index, 1); $scope.logins.splice(index, 1);
} }
}); });
}; };
@ -187,7 +187,7 @@
return false; return false;
} }
var sites = $filter('filter')($scope.sites, { folderId: folder.id }); var logins = $filter('filter')($scope.logins, { folderId: folder.id });
return sites.length === 0; return logins.length === 0;
}; };
}); });

View File

@ -1,31 +1,31 @@
angular angular
.module('bit.vault') .module('bit.vault')
.controller('vaultEditSiteController', function ($scope, apiService, $uibModalInstance, cryptoService, cipherService, passwordService, siteId, folders, $analytics) { .controller('vaultEditLoginController', function ($scope, apiService, $uibModalInstance, cryptoService, cipherService, passwordService, loginId, folders, $analytics) {
$analytics.eventTrack('vaultEditSiteController', { category: 'Modal' }); $analytics.eventTrack('vaultEditLoginController', { category: 'Modal' });
$scope.folders = folders; $scope.folders = folders;
$scope.site = {}; $scope.login = {};
apiService.sites.get({ id: siteId }, function (site) { apiService.logins.get({ id: loginId }, function (login) {
$scope.site = cipherService.decryptSite(site); $scope.login = cipherService.decryptLogin(login);
}); });
$scope.save = function (model) { $scope.save = function (model) {
var site = cipherService.encryptSite(model); var login = cipherService.encryptLogin(model);
$scope.savePromise = apiService.sites.put({ id: siteId }, site, function (siteResponse) { $scope.savePromise = apiService.logins.put({ id: loginId }, login, function (loginResponse) {
$analytics.eventTrack('Edited Site'); $analytics.eventTrack('Edited Login');
var decSite = cipherService.decryptSite(siteResponse); var decLogin = cipherService.decryptLogin(loginResponse);
$uibModalInstance.close({ $uibModalInstance.close({
action: 'edit', action: 'edit',
data: decSite data: decLogin
}); });
}).$promise; }).$promise;
}; };
$scope.generatePassword = function () { $scope.generatePassword = function () {
if (!$scope.site.password || confirm('Are you sure you want to overwrite the current password?')) { if (!$scope.login.password || confirm('Are you sure you want to overwrite the current password?')) {
$analytics.eventTrack('Generated Password From Edit'); $analytics.eventTrack('Generated Password From Edit');
$scope.site.password = passwordService.generatePassword({ length: 10, special: true }); $scope.login.password = passwordService.generatePassword({ length: 10, special: true });
} }
}; };
@ -53,14 +53,14 @@
} }
$scope.delete = function () { $scope.delete = function () {
if (!confirm('Are you sure you want to delete this site (' + $scope.site.name + ')?')) { if (!confirm('Are you sure you want to delete this login (' + $scope.login.name + ')?')) {
return; return;
} }
apiService.sites.del({ id: $scope.site.id }, function () { apiService.logins.del({ id: $scope.login.id }, function () {
$uibModalInstance.close({ $uibModalInstance.close({
action: 'delete', action: 'delete',
data: $scope.site.id data: $scope.login.id
}); });
}); });
}; };

View File

@ -1,7 +1,7 @@
<section class="content-header"> <section class="content-header">
<h1> <h1>
My Vault My Vault
<small>{{folders.length > 0 ? folders.length - 1 : 0}} folders, {{sites.length}} sites</small> <small>{{folders.length > 0 ? folders.length - 1 : 0}} folders, {{logins.length}} logins</small>
</h1> </h1>
</section> </section>
<section class="content"> <section class="content">
@ -10,9 +10,9 @@
</div> </div>
<div class="box" ng-repeat="folder in folders | orderBy: folderSort" ng-show="folders.length"> <div class="box" ng-repeat="folder in folders | orderBy: folderSort" ng-show="folders.length">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title"><i class="fa fa-folder-open"></i> {{folder.name}} <small>{{folderSites.length}} sites</small></h3> <h3 class="box-title"><i class="fa fa-folder-open"></i> {{folder.name}} <small>{{folderLogins.length}} logins</small></h3>
<div class="box-tools pull-right"> <div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool" ng-click="addSite(folder)" uib-tooltip="Add Site"> <button type="button" class="btn btn-box-tool" ng-click="addLogin(folder)" uib-tooltip="Add Login">
<i class="fa fa-plus"></i> <i class="fa fa-plus"></i>
</button> </button>
<button type="button" class="btn btn-box-tool" ng-click="deleteFolder(folder)" ng-show="canDeleteFolder(folder)" uib-tooltip="Delete"> <button type="button" class="btn btn-box-tool" ng-click="deleteFolder(folder)" ng-show="canDeleteFolder(folder)" uib-tooltip="Delete">
@ -26,31 +26,31 @@
</button> </button>
</div> </div>
</div> </div>
<div class="box-body" ng-class="{'no-padding': folderSites.length}"> <div class="box-body" ng-class="{'no-padding': folderLogins.length}">
<div ng-show="loadingSites && !folderSites.length"> <div ng-show="loadingLogins && !folderLogins.length">
<p>Loading sites...</p> <p>Loading logins...</p>
</div> </div>
<div ng-show="!loadingSites && !folderSites.length"> <div ng-show="!loadingLogins && !folderLogins.length">
<p>No sites in this folder.</p> <p>No logins in this folder.</p>
<button type="button" ng-click="addSite(folder)" class="btn btn-default btn-flat">Add a Site</button> <button type="button" ng-click="addLogin(folder)" class="btn btn-default btn-flat">Add a Login</button>
</div> </div>
<div class="table-responsive" ng-show="folderSites.length"> <div class="table-responsive" ng-show="folderLogins.length">
<table class="table table-striped table-hover"> <table class="table table-striped table-hover">
<thead> <thead>
<tr> <tr>
<th style="width: 75px; min-width: 75px;"></th> <th style="width: 75px; min-width: 75px;"></th>
<th>Site</th> <th>Name</th>
<th style="width: 300px;">Username</th> <th style="width: 300px;">Username</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr ng-repeat="site in folderSites = (sites | filter: { folderId: folder.id } | filter: (main.searchVaultText || '') | orderBy: ['name', 'username'])"> <tr ng-repeat="login in folderLogins = (logins | filter: { folderId: folder.id } | filter: (main.searchVaultText || '') | orderBy: ['name', 'username'])">
<td> <td>
<button type="button" ng-click="deleteSite(site)" class="btn btn-link btn-table" uib-tooltip="Delete"><i class="fa fa-lg fa-trash"></i></button> <button type="button" ng-click="deleteLogin(login)" class="btn btn-link btn-table" uib-tooltip="Delete"><i class="fa fa-lg fa-trash"></i></button>
<button type="button" ng-click="editSite(site)" class="btn btn-link btn-table" uib-tooltip="View/Edit"><i class="fa fa-lg fa-pencil"></i></button> <button type="button" ng-click="editLogin(login)" class="btn btn-link btn-table" uib-tooltip="View/Edit"><i class="fa fa-lg fa-pencil"></i></button>
</td> </td>
<td>{{site.name}} <i class="fa fa-star text-muted" uib-tooltip="Favorite" ng-show="site.favorite"></i></td> <td>{{login.name}} <i class="fa fa-star text-muted" uib-tooltip="Favorite" ng-show="login.favorite"></i></td>
<td>{{site.username}}</td> <td>{{login.username}}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@ -1,19 +1,19 @@
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" ng-click="close()" aria-label="Close"><span aria-hidden="true">&times;</span></button> <button type="button" class="close" ng-click="close()" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="addSiteModelLabel"><i class="fa fa-globe"></i> Add New Site</h4> <h4 class="modal-title" id="addLoginModelLabel"><i class="fa fa-globe"></i> Add New Login</h4>
</div> </div>
<form name="addSiteForm" ng-submit="addSiteForm.$valid && save(site)" api-form="savePromise"> <form name="addLoginForm" ng-submit="addLoginForm.$valid && save(login)" api-form="savePromise">
<div class="modal-body"> <div class="modal-body">
<div class="callout callout-danger validation-errors" ng-show="addSiteForm.$errors"> <div class="callout callout-danger validation-errors" ng-show="addLoginForm.$errors">
<h4>Errors have occured</h4> <h4>Errors have occured</h4>
<ul> <ul>
<li ng-repeat="e in addSiteForm.$errors">{{e}}</li> <li ng-repeat="e in addLoginForm.$errors">{{e}}</li>
</ul> </ul>
</div> </div>
<div class="form-group" show-errors> <div class="form-group" show-errors>
<label for="uri">URI</label> <label for="uri">URI</label>
<div class="input-group"> <div class="input-group">
<input type="text" id="uri" ng-model="site.uri" name="Uri" class="form-control" placeholder="http://..." api-field /> <input type="text" id="uri" ng-model="login.uri" name="Uri" class="form-control" placeholder="http://..." api-field />
<span class="input-group-btn" uib-tooltip="Copy URI" tooltip-placement="left"> <span class="input-group-btn" uib-tooltip="Copy URI" tooltip-placement="left">
<button tabindex="-1" class="btn btn-default btn-flat" type="button" ngclipboard <button tabindex="-1" class="btn btn-default btn-flat" type="button" ngclipboard
ngclipboard-error="clipboardError(e)" ngclipboard-error="clipboardError(e)"
@ -27,13 +27,13 @@
<div class="col-md-6"> <div class="col-md-6">
<div class="form-group" show-errors> <div class="form-group" show-errors>
<label for="name">Name</label> <label for="name">Name</label>
<input type="text" id="name" name="Name" ng-model="site.name" class="form-control" required api-field /> <input type="text" id="name" name="Name" ng-model="login.name" class="form-control" required api-field />
</div> </div>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<div class="form-group" show-errors> <div class="form-group" show-errors>
<label for="folder">Folder</label> <label for="folder">Folder</label>
<select id="folder" name="FolderId" ng-model="site.folderId" class="form-control" api-field> <select id="folder" name="FolderId" ng-model="login.folderId" class="form-control" api-field>
<option ng-repeat="folder in folders | orderBy: folderSort" value="{{folder.id}}">{{folder.name}}</option> <option ng-repeat="folder in folders | orderBy: folderSort" value="{{folder.id}}">{{folder.name}}</option>
</select> </select>
</div> </div>
@ -44,7 +44,7 @@
<div class="form-group" show-errors> <div class="form-group" show-errors>
<label for="username">Username</label> <label for="username">Username</label>
<div class="input-group"> <div class="input-group">
<input type="text" id="username" name="Username" ng-model="site.username" class="form-control" api-field /> <input type="text" id="username" name="Username" ng-model="login.username" class="form-control" api-field />
<span class="input-group-btn" uib-tooltip="Copy Username" tooltip-placement="left"> <span class="input-group-btn" uib-tooltip="Copy Username" tooltip-placement="left">
<button tabindex="-1" class="btn btn-default btn-flat" type="button" ngclipboard <button tabindex="-1" class="btn btn-default btn-flat" type="button" ngclipboard
ngclipboard-error="clipboardError(e)" ngclipboard-error="clipboardError(e)"
@ -63,8 +63,8 @@
</div> </div>
<label for="password">Password</label> <label for="password">Password</label>
<div class="input-group"> <div class="input-group">
<input tabindex="-1" type="text" id="password-text" value="{{site.password}}" style="margin-left: -9999px;" /> <input tabindex="-1" type="text" id="password-text" value="{{login.password}}" style="margin-left: -9999px;" />
<input type="password" id="password" name="Password" ng-model="site.password" class="form-control" api-field /> <input type="password" id="password" name="Password" ng-model="login.password" class="form-control" api-field />
<span class="input-group-btn" uib-tooltip="Copy Password" tooltip-placement="left"> <span class="input-group-btn" uib-tooltip="Copy Password" tooltip-placement="left">
<button tabindex="-1" class="btn btn-default btn-flat" type="button" ngclipboard <button tabindex="-1" class="btn btn-default btn-flat" type="button" ngclipboard
ngclipboard-success="clipboardSuccess(e)" ngclipboard-success="clipboardSuccess(e)"
@ -75,23 +75,23 @@
</span> </span>
</div> </div>
</div> </div>
<div style="margin: -10px 0 15px 0;" password-meter="site.password" password-meter-username="site.username" outer-class="xs"></div> <div style="margin: -10px 0 15px 0;" password-meter="login.password" password-meter-username="login.username" outer-class="xs"></div>
</div> </div>
</div> </div>
<div class="form-group" show-errors> <div class="form-group" show-errors>
<label for="notes">Notes</label> <label for="notes">Notes</label>
<textarea id="notes" name="Notes" class="form-control" ng-model="site.notes" api-field></textarea> <textarea id="notes" name="Notes" class="form-control" ng-model="login.notes" api-field></textarea>
</div> </div>
<div class="checkbox"> <div class="checkbox">
<label> <label>
<input type="checkbox" ng-model="site.favorite" name="Favorite" /> <input type="checkbox" ng-model="login.favorite" name="Favorite" />
Favorite Favorite
</label> </label>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" class="btn btn-primary btn-flat" ng-disabled="addSiteForm.$loading"> <button type="submit" class="btn btn-primary btn-flat" ng-disabled="addLoginForm.$loading">
<i class="fa fa-refresh fa-spin loading-icon" ng-show="addSiteForm.$loading"></i>Submit <i class="fa fa-refresh fa-spin loading-icon" ng-show="addLoginForm.$loading"></i>Submit
</button> </button>
<button type="button" class="btn btn-default btn-flat" ng-click="close()">Close</button> <button type="button" class="btn btn-default btn-flat" ng-click="close()">Close</button>
</div> </div>

View File

@ -1,26 +1,26 @@
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" ng-click="close()" aria-label="Close"><span aria-hidden="true">&times;</span></button> <button type="button" class="close" ng-click="close()" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="editSiteModelLabel"><i class="fa fa-globe"></i> Site Information <small>{{site.name}}</small></h4> <h4 class="modal-title" id="editLoginModelLabel"><i class="fa fa-globe"></i> Login Information <small>{{login.name}}</small></h4>
</div> </div>
<form name="editSiteForm" ng-submit="editSiteForm.$valid && save(site)" api-form="savePromise"> <form name="editLoginForm" ng-submit="editLoginForm.$valid && save(login)" api-form="savePromise">
<div class="modal-body"> <div class="modal-body">
<div class="callout callout-danger validation-errors" ng-show="editSiteForm.$errors"> <div class="callout callout-danger validation-errors" ng-show="editLoginForm.$errors">
<h4>Errors have occured</h4> <h4>Errors have occured</h4>
<ul> <ul>
<li ng-repeat="e in editSiteForm.$errors">{{e}}</li> <li ng-repeat="e in editLoginForm.$errors">{{e}}</li>
</ul> </ul>
</div> </div>
<div class="form-group" show-errors> <div class="form-group" show-errors>
<label for="uri">URI</label> <label for="uri">URI</label>
<div class="input-group"> <div class="input-group">
<input type="text" id="uri" name="Uri" ng-model="site.uri" class="form-control" placeholder="http://..." api-field /> <input type="text" id="uri" name="Uri" ng-model="login.uri" class="form-control" placeholder="http://..." api-field />
<span class="input-group-btn"> <span class="input-group-btn">
<button tabindex="-1" class="btn btn-default btn-flat" type="button" uib-tooltip="Copy URI" tooltip-placement="left" ngclipboard <button tabindex="-1" class="btn btn-default btn-flat" type="button" uib-tooltip="Copy URI" tooltip-placement="left" ngclipboard
ngclipboard-error="clipboardError(e)" ngclipboard-error="clipboardError(e)"
data-clipboard-target="#uri"> data-clipboard-target="#uri">
<i class="fa fa-clipboard"></i> <i class="fa fa-clipboard"></i>
</button> </button>
<a href="{{site.uri}}" target="_blank" class="btn btn-default btn-flat" uib-tooltip="Go To Site" tooltip-placement="left"> <a href="{{login.uri}}" target="_blank" class="btn btn-default btn-flat" uib-tooltip="Go To Login" tooltip-placement="left">
<i class="fa fa-share"></i> <i class="fa fa-share"></i>
</a> </a>
</span> </span>
@ -30,13 +30,13 @@
<div class="col-md-6"> <div class="col-md-6">
<div class="form-group" show-errors> <div class="form-group" show-errors>
<label for="name">Name</label> <label for="name">Name</label>
<input type="text" id="name" name="Name" ng-model="site.name" class="form-control" required api-field /> <input type="text" id="name" name="Name" ng-model="login.name" class="form-control" required api-field />
</div> </div>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<div class="form-group" show-errors> <div class="form-group" show-errors>
<label for="folder">Folder</label> <label for="folder">Folder</label>
<select id="folder" name="FolderId" ng-model="site.folderId" class="form-control" api-field> <select id="folder" name="FolderId" ng-model="login.folderId" class="form-control" api-field>
<option ng-repeat="folder in folders | orderBy: folderSort" value="{{folder.id}}">{{folder.name}}</option> <option ng-repeat="folder in folders | orderBy: folderSort" value="{{folder.id}}">{{folder.name}}</option>
</select> </select>
</div> </div>
@ -47,7 +47,7 @@
<div class="form-group" show-errors> <div class="form-group" show-errors>
<label for="username">Username</label> <label for="username">Username</label>
<div class="input-group"> <div class="input-group">
<input type="text" id="username" name="Username" ng-model="site.username" class="form-control" api-field /> <input type="text" id="username" name="Username" ng-model="login.username" class="form-control" api-field />
<span class="input-group-btn" uib-tooltip="Copy Username" tooltip-placement="left"> <span class="input-group-btn" uib-tooltip="Copy Username" tooltip-placement="left">
<button tabindex="-1" class="btn btn-default btn-flat" type="button" ngclipboard <button tabindex="-1" class="btn btn-default btn-flat" type="button" ngclipboard
ngclipboard-error="clipboardError(e)" ngclipboard-error="clipboardError(e)"
@ -66,8 +66,8 @@
</div> </div>
<label for="password">Password</label> <label for="password">Password</label>
<div class="input-group"> <div class="input-group">
<input type="text" id="password-text" value="{{site.password}}" style="margin-left: -9999px;" /> <input type="text" id="password-text" value="{{login.password}}" style="margin-left: -9999px;" />
<input type="password" id="password" name="Password" ng-model="site.password" class="form-control" api-field /> <input type="password" id="password" name="Password" ng-model="login.password" class="form-control" api-field />
<span class="input-group-btn" uib-tooltip="Copy Password" tooltip-placement="left"> <span class="input-group-btn" uib-tooltip="Copy Password" tooltip-placement="left">
<button tabindex="-1" class="btn btn-default btn-flat" type="button" ngclipboard <button tabindex="-1" class="btn btn-default btn-flat" type="button" ngclipboard
ngclipboard-success="clipboardSuccess(e)" ngclipboard-success="clipboardSuccess(e)"
@ -78,23 +78,23 @@
</span> </span>
</div> </div>
</div> </div>
<div style="margin: -10px 0 15px 0;" password-meter="site.password" password-meter-username="site.username" outer-class="xs"></div> <div style="margin: -10px 0 15px 0;" password-meter="login.password" password-meter-username="login.username" outer-class="xs"></div>
</div> </div>
</div> </div>
<div class="form-group" show-errors> <div class="form-group" show-errors>
<label for="notes">Notes</label> <label for="notes">Notes</label>
<textarea id="notes" name="Notes" class="form-control" ng-model="site.notes" api-field></textarea> <textarea id="notes" name="Notes" class="form-control" ng-model="login.notes" api-field></textarea>
</div> </div>
<div class="checkbox"> <div class="checkbox">
<label> <label>
<input type="checkbox" ng-model="site.favorite" name="Favorite" /> <input type="checkbox" ng-model="login.favorite" name="Favorite" />
Favorite Favorite
</label> </label>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" class="btn btn-primary btn-flat" ng-disabled="editSiteForm.$loading"> <button type="submit" class="btn btn-primary btn-flat" ng-disabled="editLoginForm.$loading">
<i class="fa fa-refresh fa-spin loading-icon" ng-show="editSiteForm.$loading"></i>Save <i class="fa fa-refresh fa-spin loading-icon" ng-show="editLoginForm.$loading"></i>Save
</button> </button>
<button type="button" class="btn btn-default btn-flat" ng-click="close()">Close</button> <button type="button" class="btn btn-default btn-flat" ng-click="close()">Close</button>
<button type="button" class="btn btn-link pull-right" ng-click="delete()" uib-tooltip="Delete"> <button type="button" class="btn btn-link pull-right" ng-click="delete()" uib-tooltip="Delete">

View File

@ -45,8 +45,8 @@
<a ui-sref="backend.vault"><i class="fa fa-lock"></i> <span>My Vault</span></a> <a ui-sref="backend.vault"><i class="fa fa-lock"></i> <span>My Vault</span></a>
<ul class="treeview-menu menu-open"> <ul class="treeview-menu menu-open">
<li> <li>
<a href="javascript:void(0)" ng-click="addSite()"> <a href="javascript:void(0)" ng-click="addLogin()">
<i class="fa fa-plus"></i> New Site <i class="fa fa-plus"></i> New Login
</a> </a>
</li> </li>
<li> <li>

View File

@ -114,8 +114,8 @@
<script src="app/vault/vaultModule.js"></script> <script src="app/vault/vaultModule.js"></script>
<script src="app/vault/vaultController.js"></script> <script src="app/vault/vaultController.js"></script>
<script src="app/vault/vaultEditSiteController.js"></script> <script src="app/vault/vaultEditLoginController.js"></script>
<script src="app/vault/vaultAddSiteController.js"></script> <script src="app/vault/vaultAddLoginController.js"></script>
<script src="app/vault/vaultEditFolderController.js"></script> <script src="app/vault/vaultEditFolderController.js"></script>
<script src="app/vault/vaultAddFolderController.js"></script> <script src="app/vault/vaultAddFolderController.js"></script>