mirror of
https://github.com/bitwarden/browser
synced 2025-12-14 23:33:31 +00:00
244 lines
7.7 KiB
JavaScript
244 lines
7.7 KiB
JavaScript
angular
|
|
.module('bit.vault')
|
|
|
|
.controller('vaultViewGroupingController', function ($scope, cipherService, folderService, $q, $state, $stateParams, toastr,
|
|
syncService, $analytics, i18nService, stateService, utilsService, $timeout, $window, collectionService) {
|
|
var stateKey = 'viewGrouping',
|
|
state = stateService.getState(stateKey) || {};
|
|
|
|
state.folderId = $stateParams.folderId || state.folderId;
|
|
state.collectionId = $stateParams.collectionId || state.collectionId;
|
|
|
|
var pageSize = 100,
|
|
decGrouping = null,
|
|
decCiphers = [];
|
|
|
|
$scope.grouping = {
|
|
id: null,
|
|
name: i18nService.noneFolder
|
|
};
|
|
$scope.folderGrouping = false;
|
|
$scope.collectionGrouping = false;
|
|
|
|
if (state.folderId && state.folderId !== '0') {
|
|
$scope.grouping.id = state.folderId;
|
|
$scope.folderGrouping = true;
|
|
}
|
|
else if (state.collectionId && state.collectionId !== '0') {
|
|
$scope.grouping.id = state.collectionId;
|
|
$scope.collectionGrouping = true;
|
|
}
|
|
|
|
$scope.i18n = i18nService;
|
|
document.getElementById('search').focus();
|
|
|
|
$scope.loaded = false;
|
|
$scope.vaultCiphers = [];
|
|
$scope.pagedVaultCiphers = [];
|
|
$scope.searchText = null;
|
|
loadVault();
|
|
|
|
function loadVault() {
|
|
var promises = [];
|
|
|
|
if ($scope.grouping.id && $scope.folderGrouping) {
|
|
var getPromise = folderService.get($scope.grouping.id).then(function (folder) {
|
|
return folder.decrypt();
|
|
}).then(function (model) {
|
|
decGrouping = model;
|
|
});
|
|
promises.push(getPromise);
|
|
}
|
|
else if ($scope.grouping.id && $scope.collectionGrouping) {
|
|
var getPromise = collectionService.get($scope.grouping.id).then(function (collection) {
|
|
return collection.decrypt();
|
|
}).then(function (model) {
|
|
decGrouping = model;
|
|
});
|
|
promises.push(getPromise);
|
|
}
|
|
|
|
var cipherPromise = cipherService.getAllDecryptedForGrouping($scope.grouping.id, $scope.folderGrouping)
|
|
.then(function (ciphers) {
|
|
if (utilsService.isEdge()) {
|
|
// Edge is super slow at sorting
|
|
decCiphers = ciphers;
|
|
}
|
|
else {
|
|
decCiphers = ciphers.sort(cipherSort);
|
|
}
|
|
});
|
|
promises.push(cipherPromise);
|
|
|
|
$q.all(promises).then(function () {
|
|
$scope.loaded = true;
|
|
$scope.vaultCiphers = decCiphers;
|
|
|
|
if (decGrouping) {
|
|
$scope.grouping.name = decGrouping.name;
|
|
}
|
|
|
|
if (state.searchText) {
|
|
$scope.searchText = state.searchText;
|
|
$scope.searchCiphers();
|
|
}
|
|
|
|
$timeout(setScrollY, 200);
|
|
});
|
|
}
|
|
|
|
function cipherSort(a, b) {
|
|
if (!a.name) {
|
|
return -1;
|
|
}
|
|
if (!b.name) {
|
|
return 1;
|
|
}
|
|
|
|
var aName = a.name.toLowerCase(),
|
|
bName = b.name.toLowerCase();
|
|
if (aName > bName) {
|
|
return 1;
|
|
}
|
|
if (aName < bName) {
|
|
return -1;
|
|
}
|
|
|
|
if (!a.subTitle) {
|
|
return -1;
|
|
}
|
|
if (!b.subTitle) {
|
|
return 1;
|
|
}
|
|
|
|
var aSubTitle = a.subTitle.toLowerCase(),
|
|
bSubTitle = b.subTitle.toLowerCase();
|
|
if (aSubTitle > bSubTitle) {
|
|
return 1;
|
|
}
|
|
if (aSubTitle < bSubTitle) {
|
|
return -1;
|
|
}
|
|
|
|
// a must be equal to b
|
|
return 0;
|
|
}
|
|
|
|
$scope.loadMore = function () {
|
|
var pagedLength = $scope.pagedVaultCiphers.length;
|
|
if ($scope.vaultCiphers.length > pagedLength) {
|
|
$scope.pagedVaultCiphers =
|
|
$scope.pagedVaultCiphers.concat($scope.vaultCiphers.slice(pagedLength, pagedLength + pageSize));
|
|
}
|
|
};
|
|
|
|
$scope.searchCiphers = function () {
|
|
if (!$scope.searchText || $scope.searchText.length < 2) {
|
|
if ($scope.vaultCiphers.length !== decCiphers.length) {
|
|
resetList(decCiphers);
|
|
}
|
|
return;
|
|
}
|
|
|
|
var matchedCiphers = [];
|
|
for (var i = 0; i < decCiphers.length; i++) {
|
|
if (searchCipher(decCiphers[i])) {
|
|
matchedCiphers.push(decCiphers[i]);
|
|
}
|
|
}
|
|
|
|
resetList(matchedCiphers);
|
|
};
|
|
|
|
function resetList(ciphers) {
|
|
$scope.vaultCiphers = ciphers;
|
|
$scope.pagedVaultCiphers = [];
|
|
$scope.loadMore();
|
|
}
|
|
|
|
function searchCipher(cipher) {
|
|
var searchTerm = $scope.searchText.toLowerCase();
|
|
if (cipher.name && cipher.name.toLowerCase().indexOf(searchTerm) !== -1) {
|
|
return true;
|
|
}
|
|
if (cipher.subTitle && cipher.subTitle.toLowerCase().indexOf(searchTerm) !== -1) {
|
|
return true;
|
|
}
|
|
if (cipher.login && cipher.login.uri && cipher.login.uri.toLowerCase().indexOf(searchTerm) !== -1) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
$scope.addCipher = function () {
|
|
storeState();
|
|
$state.go('addCipher', {
|
|
animation: 'in-slide-up',
|
|
from: 'grouping',
|
|
folderId: state.folderId
|
|
});
|
|
};
|
|
|
|
$scope.viewCipher = function (cipher) {
|
|
var canLaunch = cipher.login && cipher.login.uri &&
|
|
(cipher.login.uri.startsWith('http://') || cipher.login.uri.startsWith('https://'));
|
|
if (canLaunch && cipher.clicked) {
|
|
cipher.cancelClick = true;
|
|
cipher.clicked = false;
|
|
$scope.launchWebsite(cipher);
|
|
return;
|
|
}
|
|
|
|
cipher.clicked = true;
|
|
cipher.cancelClick = false;
|
|
|
|
$timeout(function () {
|
|
if (cipher.cancelClick) {
|
|
cipher.cancelClick = false;
|
|
cipher.clicked = false;
|
|
return;
|
|
}
|
|
|
|
storeState();
|
|
$state.go('viewCipher', {
|
|
cipherId: cipher.id,
|
|
animation: 'in-slide-up',
|
|
from: 'grouping'
|
|
});
|
|
|
|
// clean up
|
|
cipher.cancelClick = false;
|
|
cipher.clicked = false;
|
|
}, 200);
|
|
};
|
|
|
|
$scope.launchWebsite = function (cipher) {
|
|
if (cipher.login && cipher.login.uri) {
|
|
$analytics.eventTrack('Launched Website');
|
|
chrome.tabs.create({ url: cipher.login.uri });
|
|
}
|
|
};
|
|
|
|
function storeState() {
|
|
angular.extend(state, {
|
|
scrollY: getScrollY(),
|
|
searchText: $scope.searchText
|
|
});
|
|
|
|
stateService.saveState(stateKey, state);
|
|
}
|
|
|
|
function getScrollY() {
|
|
var content = document.getElementsByClassName('content')[0];
|
|
return content.scrollTop;
|
|
}
|
|
|
|
function setScrollY() {
|
|
if (state.scrollY) {
|
|
var content = document.getElementsByClassName('content')[0];
|
|
content.scrollTop = state.scrollY;
|
|
}
|
|
}
|
|
});
|