mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-27 12:36:14 +01:00
converting logins to ciphers on vault lists
This commit is contained in:
parent
355a58f67c
commit
884bce4ec4
@ -72,7 +72,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
_service.logOut = function (callback) {
|
_service.logOut = function (callback) {
|
||||||
$rootScope.vaultLogins = null;
|
$rootScope.vaultCiphers = null;
|
||||||
$rootScope.vaultFolders = null;
|
$rootScope.vaultFolders = null;
|
||||||
callback();
|
callback();
|
||||||
};
|
};
|
||||||
|
@ -22,8 +22,8 @@
|
|||||||
|
|
||||||
var delayLoad = true;
|
var delayLoad = true;
|
||||||
$scope.loaded = true;
|
$scope.loaded = true;
|
||||||
if (!$rootScope.vaultLogins) {
|
if (!$rootScope.vaultCiphers) {
|
||||||
$rootScope.vaultLogins = [];
|
$rootScope.vaultCiphers = [];
|
||||||
delayLoad = false;
|
delayLoad = false;
|
||||||
}
|
}
|
||||||
if (!$rootScope.vaultFolders) {
|
if (!$rootScope.vaultFolders) {
|
||||||
@ -42,32 +42,30 @@
|
|||||||
|
|
||||||
function loadVault() {
|
function loadVault() {
|
||||||
var decFolders = [];
|
var decFolders = [];
|
||||||
var decLogins = [];
|
var decCiphers = [];
|
||||||
var promises = [];
|
var promises = [];
|
||||||
|
|
||||||
var folderPromise = $q.when(folderService.getAllDecrypted());
|
var folderPromise = folderService.getAllDecrypted().then(function (folders) {
|
||||||
folderPromise.then(function (folders) {
|
|
||||||
decFolders = folders;
|
decFolders = folders;
|
||||||
});
|
});
|
||||||
promises.push(folderPromise);
|
promises.push(folderPromise);
|
||||||
|
|
||||||
var cipherPromise = loginService.getAllDecrypted();
|
var cipherPromise = loginService.getAllDecrypted().then(function (ciphers) {
|
||||||
cipherPromise.then(function (ciphers) {
|
decCiphers = ciphers;
|
||||||
decLogins = ciphers;
|
|
||||||
});
|
});
|
||||||
promises.push(cipherPromise);
|
promises.push(cipherPromise);
|
||||||
|
|
||||||
$q.all(promises).then(function () {
|
$q.all(promises).then(function () {
|
||||||
$scope.loaded = true;
|
$scope.loaded = true;
|
||||||
$rootScope.vaultFolders = decFolders;
|
$rootScope.vaultFolders = decFolders;
|
||||||
$rootScope.vaultLogins = decLogins;
|
$rootScope.vaultCiphers = decCiphers;
|
||||||
|
|
||||||
if ($scope.showFolderCounts) {
|
if ($scope.showFolderCounts) {
|
||||||
// compute item count for each folder
|
// compute item count for each folder
|
||||||
for (var i = 0; i < decFolders.length; i++) {
|
for (var i = 0; i < decFolders.length; i++) {
|
||||||
var itemCount = 0;
|
var itemCount = 0;
|
||||||
for (var j = 0; j < decLogins.length; j++) {
|
for (var j = 0; j < decCiphers.length; j++) {
|
||||||
if (decLogins[j].folderId === decFolders[i].id) {
|
if (decCiphers[j].folderId === decFolders[i].id) {
|
||||||
itemCount++;
|
itemCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -95,30 +93,30 @@
|
|||||||
return item.name.toLowerCase();
|
return item.name.toLowerCase();
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.searchLogins = function () {
|
$scope.searchCiphers = function () {
|
||||||
if (!$scope.searchText || $scope.searchText.length < 2) {
|
if (!$scope.searchText || $scope.searchText.length < 2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return searchLogin;
|
return searchCipher;
|
||||||
};
|
};
|
||||||
|
|
||||||
function searchLogin(login) {
|
function searchCipher(cipher) {
|
||||||
var searchTerm = $scope.searchText.toLowerCase();
|
var searchTerm = $scope.searchText.toLowerCase();
|
||||||
if (login.name && login.name.toLowerCase().indexOf(searchTerm) !== -1) {
|
if (cipher.name && cipher.name.toLowerCase().indexOf(searchTerm) !== -1) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (login.username && login.username.toLowerCase().indexOf(searchTerm) !== -1) {
|
if (cipher.username && cipher.username.toLowerCase().indexOf(searchTerm) !== -1) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (login.uri && login.uri.toLowerCase().indexOf(searchTerm) !== -1) {
|
if (cipher.login && cipher.login.uri && cipher.login.uri.toLowerCase().indexOf(searchTerm) !== -1) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.addLogin = function () {
|
$scope.addCipher = function () {
|
||||||
storeState();
|
storeState();
|
||||||
$state.go('addLogin', {
|
$state.go('addLogin', {
|
||||||
animation: 'in-slide-up',
|
animation: 'in-slide-up',
|
||||||
@ -126,32 +124,32 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.viewLogin = function (login) {
|
$scope.viewCipher = function (cipher) {
|
||||||
if (login.clicked) {
|
if (cipher.clicked) {
|
||||||
login.cancelClick = true;
|
cipher.cancelClick = true;
|
||||||
$scope.launchWebsite(login);
|
$scope.launchWebsite(cipher);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
login.clicked = true;
|
cipher.clicked = true;
|
||||||
|
|
||||||
$timeout(function () {
|
$timeout(function () {
|
||||||
if (login.cancelClick) {
|
if (cipher.cancelClick) {
|
||||||
login.cancelClick = false;
|
cipher.cancelClick = false;
|
||||||
login.clicked = false;
|
cipher.clicked = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
storeState();
|
storeState();
|
||||||
$state.go('viewLogin', {
|
$state.go('viewLogin', {
|
||||||
loginId: login.id,
|
loginId: cipher.id,
|
||||||
animation: 'in-slide-up',
|
animation: 'in-slide-up',
|
||||||
from: 'vault'
|
from: 'vault'
|
||||||
});
|
});
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
login.cancelClick = false;
|
cipher.cancelClick = false;
|
||||||
login.clicked = false;
|
cipher.clicked = false;
|
||||||
}, 200);
|
}, 200);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -173,11 +171,11 @@
|
|||||||
toastr.info(type + i18nService.valueCopied);
|
toastr.info(type + i18nService.valueCopied);
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.launchWebsite = function (login) {
|
$scope.launchWebsite = function (cipher) {
|
||||||
$timeout(function () {
|
$timeout(function () {
|
||||||
if (login.uri.startsWith('http://') || login.uri.startsWith('https://')) {
|
if (cipher.uri.startsWith('http://') || cipher.uri.startsWith('https://')) {
|
||||||
$analytics.eventTrack('Launched Website From Listing');
|
$analytics.eventTrack('Launched Website From Listing');
|
||||||
chrome.tabs.create({ url: login.uri });
|
chrome.tabs.create({ url: cipher.uri });
|
||||||
if (utilsService.inPopup($window)) {
|
if (utilsService.inPopup($window)) {
|
||||||
$window.close();
|
$window.close();
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
var pageSize = 100,
|
var pageSize = 100,
|
||||||
decFolder = null,
|
decFolder = null,
|
||||||
decLogins = [];
|
decCiphers = [];
|
||||||
|
|
||||||
$scope.folder = {
|
$scope.folder = {
|
||||||
id: !state.folderId || state.folderId === '0' ? null : state.folderId,
|
id: !state.folderId || state.folderId === '0' ? null : state.folderId,
|
||||||
@ -20,8 +20,8 @@
|
|||||||
$('#search').focus();
|
$('#search').focus();
|
||||||
|
|
||||||
$scope.loaded = false;
|
$scope.loaded = false;
|
||||||
$scope.vaultLogins = [];
|
$scope.vaultCiphers = [];
|
||||||
$scope.pagedVaultLogins = [];
|
$scope.pagedVaultCiphers = [];
|
||||||
$scope.searchText = null;
|
$scope.searchText = null;
|
||||||
loadVault();
|
loadVault();
|
||||||
|
|
||||||
@ -31,7 +31,7 @@
|
|||||||
if ($scope.folder.id) {
|
if ($scope.folder.id) {
|
||||||
var folderDeferred = $q.defer();
|
var folderDeferred = $q.defer();
|
||||||
folderService.get($scope.folder.id, function (folder) {
|
folderService.get($scope.folder.id, function (folder) {
|
||||||
$q.when(folder.decrypt()).then(function (model) {
|
folder.decrypt().then(function (model) {
|
||||||
decFolder = model;
|
decFolder = model;
|
||||||
folderDeferred.resolve();
|
folderDeferred.resolve();
|
||||||
});
|
});
|
||||||
@ -39,21 +39,20 @@
|
|||||||
promises.push(folderDeferred.promise);
|
promises.push(folderDeferred.promise);
|
||||||
}
|
}
|
||||||
|
|
||||||
var cipherPromise = loginService.getAllDecryptedForFolder($scope.folder.id);
|
var cipherPromise = loginService.getAllDecryptedForFolder($scope.folder.id).then(function (ciphers) {
|
||||||
cipherPromise.then(function (ciphers) {
|
|
||||||
if (utilsService.isEdge()) {
|
if (utilsService.isEdge()) {
|
||||||
// Edge is super slow at sorting
|
// Edge is super slow at sorting
|
||||||
decLogins = ciphers;
|
decCiphers = ciphers;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
decLogins = ciphers.sort(cipherSort);
|
decCiphers = ciphers.sort(cipherSort);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
promises.push(cipherPromise);
|
promises.push(cipherPromise);
|
||||||
|
|
||||||
$q.all(promises).then(function () {
|
$q.all(promises).then(function () {
|
||||||
$scope.loaded = true;
|
$scope.loaded = true;
|
||||||
$scope.vaultLogins = decLogins;
|
$scope.vaultCiphers = decCiphers;
|
||||||
|
|
||||||
if (decFolder) {
|
if (decFolder) {
|
||||||
$scope.folder.name = decFolder.name;
|
$scope.folder.name = decFolder.name;
|
||||||
@ -61,7 +60,7 @@
|
|||||||
|
|
||||||
if (state.searchText) {
|
if (state.searchText) {
|
||||||
$scope.searchText = state.searchText;
|
$scope.searchText = state.searchText;
|
||||||
$scope.searchLogins();
|
$scope.searchCiphers();
|
||||||
}
|
}
|
||||||
|
|
||||||
$timeout(setScrollY, 200);
|
$timeout(setScrollY, 200);
|
||||||
@ -106,36 +105,36 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$scope.loadMore = function () {
|
$scope.loadMore = function () {
|
||||||
var pagedLength = $scope.pagedVaultLogins.length;
|
var pagedLength = $scope.pagedVaultCiphers.length;
|
||||||
if ($scope.vaultLogins.length > pagedLength) {
|
if ($scope.vaultCiphers.length > pagedLength) {
|
||||||
$scope.pagedVaultLogins =
|
$scope.pagedVaultCiphers =
|
||||||
$scope.pagedVaultLogins.concat($scope.vaultLogins.slice(pagedLength, pagedLength + pageSize));
|
$scope.pagedVaultCiphers.concat($scope.vaultCiphers.slice(pagedLength, pagedLength + pageSize));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.searchLogins = function () {
|
$scope.searchCiphers = function () {
|
||||||
if (!$scope.searchText || $scope.searchText.length < 2) {
|
if (!$scope.searchText || $scope.searchText.length < 2) {
|
||||||
if ($scope.vaultLogins.length !== decLogins.length) {
|
if ($scope.vaultCiphers.length !== decCiphers.length) {
|
||||||
resetList(decLogins);
|
resetList(decCiphers);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var matchedLogins = [];
|
var matchedCiphers = [];
|
||||||
for (var i = 0; i < decLogins.length; i++) {
|
for (var i = 0; i < decCiphers.length; i++) {
|
||||||
if (searchCipher(decLogins[i])) {
|
if (searchCipher(decCiphers[i])) {
|
||||||
matchedLogins.push(decLogins[i]);
|
matchedCiphers.push(decCiphers[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resetList(matchedLogins);
|
resetList(matchedCiphers);
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.launchWebsite = function (login) {
|
$scope.launchWebsite = function (cipher) {
|
||||||
$timeout(function () {
|
$timeout(function () {
|
||||||
if (login.uri.startsWith('http://') || login.uri.startsWith('https://')) {
|
if (cipher.uri.startsWith('http://') || cipher.uri.startsWith('https://')) {
|
||||||
$analytics.eventTrack('Launched Website From Listing');
|
$analytics.eventTrack('Launched Website From Listing');
|
||||||
chrome.tabs.create({ url: login.uri });
|
chrome.tabs.create({ url: cipher.uri });
|
||||||
if (utilsService.inPopup($window)) {
|
if (utilsService.inPopup($window)) {
|
||||||
$window.close();
|
$window.close();
|
||||||
}
|
}
|
||||||
@ -143,9 +142,9 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function resetList(logins) {
|
function resetList(ciphers) {
|
||||||
$scope.vaultLogins = logins;
|
$scope.vaultCiphers = ciphers;
|
||||||
$scope.pagedVaultLogins = [];
|
$scope.pagedVaultCiphers = [];
|
||||||
$scope.loadMore();
|
$scope.loadMore();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,7 +163,7 @@
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.addLogin = function () {
|
$scope.addCipher = function () {
|
||||||
storeState();
|
storeState();
|
||||||
$state.go('addLogin', {
|
$state.go('addLogin', {
|
||||||
animation: 'in-slide-up',
|
animation: 'in-slide-up',
|
||||||
@ -173,32 +172,32 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.viewLogin = function (login) {
|
$scope.viewCipher = function (cipher) {
|
||||||
if (login.clicked) {
|
if (cipher.clicked) {
|
||||||
login.cancelClick = true;
|
cipher.cancelClick = true;
|
||||||
$scope.launchWebsite(login);
|
$scope.launchWebsite(cipher);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
login.clicked = true;
|
cipher.clicked = true;
|
||||||
|
|
||||||
$timeout(function () {
|
$timeout(function () {
|
||||||
if (login.cancelClick) {
|
if (cipher.cancelClick) {
|
||||||
login.cancelClick = false;
|
cipher.cancelClick = false;
|
||||||
login.clicked = false;
|
cipher.clicked = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
storeState();
|
storeState();
|
||||||
$state.go('viewLogin', {
|
$state.go('viewLogin', {
|
||||||
loginId: login.id,
|
loginId: cipher.id,
|
||||||
animation: 'in-slide-up',
|
animation: 'in-slide-up',
|
||||||
from: 'folder'
|
from: 'folder'
|
||||||
});
|
});
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
login.cancelClick = false;
|
cipher.cancelClick = false;
|
||||||
login.clicked = false;
|
cipher.clicked = false;
|
||||||
}, 200);
|
}, 200);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -7,12 +7,12 @@
|
|||||||
<i class="fa fa-search"></i>
|
<i class="fa fa-search"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<a href="" ng-click="addLogin()"><i class="fa fa-plus fa-lg"></i></a>
|
<a href="" ng-click="addCipher()"><i class="fa fa-plus fa-lg"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content content-tabs">
|
<div class="content content-tabs">
|
||||||
<!-- Folder List -->
|
<!-- Folder List -->
|
||||||
<div ng-if="vaultLogins.length && (showOnlyFolderView || vaultLogins.length >= 100) && vaultFolders.length && (!searchText || searchText.length < 2)">
|
<div ng-if="vaultCiphers.length && (showOnlyFolderView || vaultCiphers.length >= 100) && vaultFolders.length && (!searchText || searchText.length < 2)">
|
||||||
<div class="list">
|
<div class="list">
|
||||||
<div class="list-section" style="padding-bottom: 0;">
|
<div class="list-section" style="padding-bottom: 0;">
|
||||||
<div class="list-section-header">
|
<div class="list-section-header">
|
||||||
@ -29,80 +29,80 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- Grouped List -->
|
<!-- Grouped List -->
|
||||||
<div ng-if="vaultLogins.length && !showOnlyFolderView && vaultLogins.length < 100 && (!searchText || searchText.length < 2)">
|
<div ng-if="vaultCiphers.length && !showOnlyFolderView && vaultCiphers.length < 100 && (!searchText || searchText.length < 2)">
|
||||||
<div class="list">
|
<div class="list">
|
||||||
<div class="list-grouped" ng-repeat="folder in vaultFolders | orderBy: folderSort track by $index"
|
<div class="list-grouped" ng-repeat="folder in vaultFolders | orderBy: folderSort track by $index"
|
||||||
ng-show="vaultFolderLogins.length">
|
ng-show="vaultFolderCiphers.length">
|
||||||
<div class="list-grouped-header">
|
<div class="list-grouped-header">
|
||||||
<small>{{vaultFolderLogins.length}}</small>
|
<small>{{vaultFolderCiphers.length}}</small>
|
||||||
<i class="fa fa-folder-open"></i> {{folder.name}}
|
<i class="fa fa-folder-open"></i> {{folder.name}}
|
||||||
</div>
|
</div>
|
||||||
<a href="#" stop-click ng-click="viewLogin(login)"
|
<a href="#" stop-click ng-click="viewCipher(cipher)"
|
||||||
class="list-grouped-item condensed" title="{{i18n.edit}} {{login.name}}"
|
class="list-grouped-item condensed" title="{{i18n.edit}} {{cipher.name}}"
|
||||||
ng-repeat="login in vaultFolderLogins = (vaultLogins | filter: { folderId: folder.id }
|
ng-repeat="cipher in vaultFolderCiphers = (vaultCiphers | filter: { folderId: folder.id }
|
||||||
| filter: searchLogins() | orderBy: ['name', 'subTitle']) track by $index">
|
| filter: searchCiphers() | orderBy: ['name', 'subTitle']) track by $index">
|
||||||
<span class="btn-list" stop-prop stop-click title="{{i18n.copyPassword}}" ngclipboard
|
<span class="btn-list" stop-prop stop-click title="{{i18n.copyPassword}}" ngclipboard
|
||||||
ngclipboard-error="clipboardError(e)" ngclipboard-success="clipboardSuccess(e, i18n.password)"
|
ngclipboard-error="clipboardError(e)" ngclipboard-success="clipboardSuccess(e, i18n.password)"
|
||||||
data-clipboard-text="{{login.password}}" ng-class="{'disabled': !login.password}">
|
data-clipboard-text="{{cipher.password}}" ng-class="{'disabled': !cipher.password}">
|
||||||
<i class="fa fa-lg fa-key"></i>
|
<i class="fa fa-lg fa-key"></i>
|
||||||
</span>
|
</span>
|
||||||
<span class="btn-list" stop-prop stop-click title="{{i18n.copyUsername}}" ngclipboard
|
<span class="btn-list" stop-prop stop-click title="{{i18n.copyUsername}}" ngclipboard
|
||||||
ngclipboard-error="clipboardError(e)" ngclipboard-success="clipboardSuccess(e, i18n.username)"
|
ngclipboard-error="clipboardError(e)" ngclipboard-success="clipboardSuccess(e, i18n.username)"
|
||||||
data-clipboard-text="{{login.username}}" ng-class="{'disabled': !login.username}">
|
data-clipboard-text="{{cipher.username}}" ng-class="{'disabled': !cipher.username}">
|
||||||
<i class="fa fa-lg fa-user"></i>
|
<i class="fa fa-lg fa-user"></i>
|
||||||
</span>
|
</span>
|
||||||
<span class="btn-list" stop-prop stop-click title="{{i18n.launchWebsite}}" ng-click="launchWebsite(login)"
|
<span class="btn-list" stop-prop stop-click title="{{i18n.launchWebsite}}" ng-click="launchWebsite(cipher)"
|
||||||
ng-class="{'disabled': !login.uri}">
|
ng-class="{'disabled': !cipher.uri}">
|
||||||
<i class="fa fa-lg fa-share-square-o"></i>
|
<i class="fa fa-lg fa-share-square-o"></i>
|
||||||
</span>
|
</span>
|
||||||
<icon uri="login.uri"></icon>
|
<icon uri="cipher.uri"></icon>
|
||||||
<span class="text">
|
<span class="text">
|
||||||
{{login.name}}
|
{{cipher.name}}
|
||||||
<i class="fa fa-share-alt text-muted" ng-if="login.organizationId" title="{{i18n.shared}}"></i>
|
<i class="fa fa-share-alt text-muted" ng-if="cipher.organizationId" title="{{i18n.shared}}"></i>
|
||||||
<i class="fa fa-paperclip text-muted" ng-if="login.attachments" title="{{i18n.attachments}}"></i>
|
<i class="fa fa-paperclip text-muted" ng-if="cipher.attachments" title="{{i18n.attachments}}"></i>
|
||||||
</span>
|
</span>
|
||||||
<span class="detail">{{login.subTitle}}</span>
|
<span class="detail">{{cipher.subTitle}}</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- Search Results List -->
|
<!-- Search Results List -->
|
||||||
<div ng-if="vaultLogins.length && searchText && searchText.length >= 2">
|
<div ng-if="vaultCiphers.length && searchText && searchText.length >= 2">
|
||||||
<div class="list">
|
<div class="list">
|
||||||
<div class="list-section" style="padding-top: 0; padding-bottom: 0;">
|
<div class="list-section" style="padding-top: 0; padding-bottom: 0;">
|
||||||
<a href="#" stop-click ng-click="viewLogin(login)"
|
<a href="#" stop-click ng-click="viewCipher(cipher)"
|
||||||
class="list-section-item condensed" title="{{i18n.edit}} {{login.name}}"
|
class="list-section-item condensed" title="{{i18n.edit}} {{cipher.name}}"
|
||||||
ng-repeat="login in searchResults = (vaultLogins | filter: searchLogins() | orderBy: ['name', 'subTitle'])
|
ng-repeat="cipher in searchResults = (vaultCiphers | filter: searchCiphers() | orderBy: ['name', 'subTitle'])
|
||||||
track by $index">
|
track by $index">
|
||||||
<span class="btn-list" stop-prop stop-click title="{{i18n.copyPassword}}" ngclipboard
|
<span class="btn-list" stop-prop stop-click title="{{i18n.copyPassword}}" ngclipboard
|
||||||
ngclipboard-error="clipboardError(e)" ngclipboard-success="clipboardSuccess(e, i18n.password)"
|
ngclipboard-error="clipboardError(e)" ngclipboard-success="clipboardSuccess(e, i18n.password)"
|
||||||
data-clipboard-text="{{login.password}}" ng-class="{'disabled': !login.password}">
|
data-clipboard-text="{{cipher.password}}" ng-class="{'disabled': !cipher.password}">
|
||||||
<i class="fa fa-lg fa-key"></i>
|
<i class="fa fa-lg fa-key"></i>
|
||||||
</span>
|
</span>
|
||||||
<span class="btn-list" stop-prop stop-click title="{{i18n.copyUsername}}" ngclipboard
|
<span class="btn-list" stop-prop stop-click title="{{i18n.copyUsername}}" ngclipboard
|
||||||
ngclipboard-error="clipboardError(e)" ngclipboard-success="clipboardSuccess(e, i18n.username)"
|
ngclipboard-error="clipboardError(e)" ngclipboard-success="clipboardSuccess(e, i18n.username)"
|
||||||
data-clipboard-text="{{login.username}}" ng-class="{'disabled': !login.username}">
|
data-clipboard-text="{{cipher.username}}" ng-class="{'disabled': !cipher.username}">
|
||||||
<i class="fa fa-lg fa-user"></i>
|
<i class="fa fa-lg fa-user"></i>
|
||||||
</span>
|
</span>
|
||||||
<span class="btn-list" stop-prop stop-click title="{{i18n.launchWebsite}}" ng-click="launchWebsite(login)"
|
<span class="btn-list" stop-prop stop-click title="{{i18n.launchWebsite}}" ng-click="launchWebsite(cipher)"
|
||||||
ng-class="{'disabled': !login.uri}">
|
ng-class="{'disabled': !cipher.uri}">
|
||||||
<i class="fa fa-lg fa-share-square-o"></i>
|
<i class="fa fa-lg fa-share-square-o"></i>
|
||||||
</span>
|
</span>
|
||||||
<icon uri="login.uri"></icon>
|
<icon uri="cipher.uri"></icon>
|
||||||
<span class="text">
|
<span class="text">
|
||||||
{{login.name}}
|
{{cipher.name}}
|
||||||
<i class="fa fa-share-alt text-muted" ng-if="login.organizationId" title="{{i18n.shared}}"></i>
|
<i class="fa fa-share-alt text-muted" ng-if="cipher.organizationId" title="{{i18n.shared}}"></i>
|
||||||
<i class="fa fa-paperclip text-muted" ng-if="login.attachments" title="{{i18n.attachments}}"></i>
|
<i class="fa fa-paperclip text-muted" ng-if="cipher.attachments" title="{{i18n.attachments}}"></i>
|
||||||
</span>
|
</span>
|
||||||
<span class="detail">{{login.subTitle}}</span>
|
<span class="detail">{{cipher.subTitle}}</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="centered-message" ng-if="loaded && !vaultLogins.length">
|
<div class="centered-message" ng-if="loaded && !vaultCiphers.length">
|
||||||
<p>
|
<p>
|
||||||
{{i18n.noLoginsInList}}
|
{{i18n.noLoginsInList}}
|
||||||
<button ng-click="addLogin()" style="margin-top: 20px;" class="btn btn-link btn-block">{{i18n.addLogin}}</button>
|
<button ng-click="addCipher()" style="margin-top: 20px;" class="btn btn-link btn-block">{{i18n.addLogin}}</button>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="page-loading" ng-if="!loaded">
|
<div class="page-loading" ng-if="!loaded">
|
||||||
|
@ -3,53 +3,53 @@
|
|||||||
<a ui-sref="tabs.vault({animation: 'out-slide-right'})"><i class="fa fa-chevron-left"></i> {{i18n.myVault}}</a>
|
<a ui-sref="tabs.vault({animation: 'out-slide-right'})"><i class="fa fa-chevron-left"></i> {{i18n.myVault}}</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="search">
|
<div class="search">
|
||||||
<input type="search" placeholder="{{i18n.searchFolder}}" ng-model="searchText" ng-change="searchLogins()" id="search" />
|
<input type="search" placeholder="{{i18n.searchFolder}}" ng-model="searchText" ng-change="searchCiphers()" id="search" />
|
||||||
<i class="fa fa-search"></i>
|
<i class="fa fa-search"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<a href="" ng-click="addLogin()"><i class="fa fa-plus fa-lg"></i></a>
|
<a href="" ng-click="addCipher()"><i class="fa fa-plus fa-lg"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div ng-if="vaultLogins.length" infinite-scroll="loadMore()" infinite-scroll-distance="1" infinite-scroll-parent="true"
|
<div ng-if="vaultCiphers.length" infinite-scroll="loadMore()" infinite-scroll-distance="1" infinite-scroll-parent="true"
|
||||||
infinite-scroll-immediate-check="true">
|
infinite-scroll-immediate-check="true">
|
||||||
<div class="list">
|
<div class="list">
|
||||||
<div class="list-section" style="padding-bottom: 0;">
|
<div class="list-section" style="padding-bottom: 0;">
|
||||||
<div class="list-section-header">
|
<div class="list-section-header">
|
||||||
{{folder.name}}
|
{{folder.name}}
|
||||||
<span>{{vaultLogins.length}}</span>
|
<span>{{vaultCiphers.length}}</span>
|
||||||
</div>
|
</div>
|
||||||
<a href="#" stop-click ng-click="viewLogin(login)"
|
<a href="#" stop-click ng-click="viewCipher(cipher)"
|
||||||
class="list-section-item condensed" title="{{i18n.edit}} {{login.name}}"
|
class="list-section-item condensed" title="{{i18n.edit}} {{cipher.name}}"
|
||||||
ng-repeat="login in pagedVaultLogins track by $index">
|
ng-repeat="cipher in pagedVaultCiphers track by $index">
|
||||||
<span class="btn-list" stop-prop stop-click title="{{i18n.copyPassword}}" ngclipboard
|
<span class="btn-list" stop-prop stop-click title="{{i18n.copyPassword}}" ngclipboard
|
||||||
ngclipboard-error="clipboardError(e)" ngclipboard-success="clipboardSuccess(e, i18n.password)"
|
ngclipboard-error="clipboardError(e)" ngclipboard-success="clipboardSuccess(e, i18n.password)"
|
||||||
data-clipboard-text="{{login.password}}" ng-class="{'disabled': !login.password}">
|
data-clipboard-text="{{cipher.password}}" ng-class="{'disabled': !cipher.password}">
|
||||||
<i class="fa fa-lg fa-key"></i>
|
<i class="fa fa-lg fa-key"></i>
|
||||||
</span>
|
</span>
|
||||||
<span class="btn-list" stop-prop stop-click title="{{i18n.copyUsername}}" ngclipboard
|
<span class="btn-list" stop-prop stop-click title="{{i18n.copyUsername}}" ngclipboard
|
||||||
ngclipboard-error="clipboardError(e)" ngclipboard-success="clipboardSuccess(e, i18n.username)"
|
ngclipboard-error="clipboardError(e)" ngclipboard-success="clipboardSuccess(e, i18n.username)"
|
||||||
data-clipboard-text="{{login.username}}" ng-class="{'disabled': !login.username}">
|
data-clipboard-text="{{cipher.username}}" ng-class="{'disabled': !cipher.username}">
|
||||||
<i class="fa fa-lg fa-user"></i>
|
<i class="fa fa-lg fa-user"></i>
|
||||||
</span>
|
</span>
|
||||||
<span class="btn-list" stop-prop stop-click title="{{i18n.launchWebsite}}" ng-click="launchWebsite(login)"
|
<span class="btn-list" stop-prop stop-click title="{{i18n.launchWebsite}}" ng-click="launchWebsite(cipher)"
|
||||||
ng-class="{'disabled': !login.uri}">
|
ng-class="{'disabled': !cipher.uri}">
|
||||||
<i class="fa fa-lg fa-share-square-o"></i>
|
<i class="fa fa-lg fa-share-square-o"></i>
|
||||||
</span>
|
</span>
|
||||||
<span class="text">
|
<span class="text">
|
||||||
{{login.name}}
|
{{cipher.name}}
|
||||||
<i class="fa fa-share-alt text-muted" ng-if="login.organizationId" title="{{i18n.shared}}"></i>
|
<i class="fa fa-share-alt text-muted" ng-if="cipher.organizationId" title="{{i18n.shared}}"></i>
|
||||||
<i class="fa fa-paperclip text-muted" ng-if="login.attachments" title="{{i18n.attachments}}"></i>
|
<i class="fa fa-paperclip text-muted" ng-if="cipher.attachments" title="{{i18n.attachments}}"></i>
|
||||||
</span>
|
</span>
|
||||||
<span class="detail">{{login.username}}</span>
|
<span class="detail">{{cipher.username}}</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="centered-message" ng-if="loaded && !vaultLogins.length">
|
<div class="centered-message" ng-if="loaded && !vaultCiphers.length">
|
||||||
<p>
|
<p>
|
||||||
{{i18n.noLoginsInList}}
|
{{i18n.noLoginsInList}}
|
||||||
<button ng-click="addLogin()" style="margin-top: 20px;" class="btn btn-link btn-block">{{i18n.addLogin}}</button>
|
<button ng-click="addCipher()" style="margin-top: 20px;" class="btn btn-link btn-block">{{i18n.addLogin}}</button>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="page-loading" ng-if="!loaded">
|
<div class="page-loading" ng-if="!loaded">
|
||||||
|
Loading…
Reference in New Issue
Block a user