247 lines
8.7 KiB
JavaScript
247 lines
8.7 KiB
JavaScript
angular
|
|
.module('bit.vault')
|
|
|
|
.controller('vaultController', function ($scope, $rootScope, cipherService, folderService, $q, $state, $stateParams, toastr,
|
|
syncService, platformUtilsService, $analytics, i18nService, stateService, $timeout, $window, collectionService, $filter) {
|
|
var stateKey = 'vault',
|
|
state = stateService.getState(stateKey) || {};
|
|
stateService.removeState('viewGrouping');
|
|
|
|
$scope.i18n = i18nService;
|
|
$scope.showGroupingCounts = !platformUtilsService.isEdge();
|
|
$scope.disableSearch = platformUtilsService.isEdge();
|
|
$scope.showPopout = !platformUtilsService.isSafari();
|
|
document.getElementById('search').focus();
|
|
|
|
var syncOnLoad = $stateParams.syncOnLoad;
|
|
if (syncOnLoad) {
|
|
$scope.$on('$viewContentLoaded', function () {
|
|
$timeout(function () {
|
|
syncService.fullSync(true);
|
|
}, 0);
|
|
});
|
|
}
|
|
|
|
var delayLoad = true;
|
|
$scope.loaded = true;
|
|
if (!$rootScope.vaultCiphers) {
|
|
$rootScope.vaultCiphers = [];
|
|
$scope.favoriteCiphers = [];
|
|
delayLoad = false;
|
|
}
|
|
else {
|
|
$scope.favoriteCiphers = $filter('filter')($rootScope.vaultCiphers, { favorite: true });
|
|
|
|
if (!$rootScope.vaultCollections || !$rootScope.vaultCollections.length) {
|
|
$scope.noFolderCiphers = $filter('filter')($rootScope.vaultCiphers, { folderId: null });
|
|
if ($scope.noFolderCiphers.length >= 100) {
|
|
$scope.noFolderCiphers = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!$rootScope.vaultFolders) {
|
|
$rootScope.vaultFolders = [];
|
|
delayLoad = false;
|
|
$scope.loaded = false;
|
|
}
|
|
|
|
if (!$rootScope.vaultCollections) {
|
|
$rootScope.vaultCollections = [];
|
|
delayLoad = false;
|
|
$scope.loaded = false;
|
|
}
|
|
|
|
if (delayLoad) {
|
|
$timeout(setScrollY, 100);
|
|
$timeout(loadVault, 1000);
|
|
}
|
|
else if (!syncOnLoad) {
|
|
loadVault();
|
|
}
|
|
|
|
function loadVault() {
|
|
var decFolders = [];
|
|
var decCollections = [];
|
|
var decCiphers = [];
|
|
|
|
var folderPromise = folderService.getAllDecrypted().then(function (folders) {
|
|
decFolders = folders;
|
|
});
|
|
|
|
var collectionPromise = collectionService.getAllDecrypted().then(function (collections) {
|
|
decCollections = collections;
|
|
});
|
|
|
|
var cipherPromise = cipherService.getAllDecrypted().then(function (ciphers) {
|
|
decCiphers = ciphers;
|
|
});
|
|
|
|
$q.all([folderPromise, collectionPromise, cipherPromise]).then(function () {
|
|
$scope.loaded = true;
|
|
$rootScope.vaultFolders = decFolders;
|
|
$rootScope.vaultCollections = decCollections;
|
|
$rootScope.vaultCiphers = decCiphers;
|
|
$scope.favoriteCiphers = $filter('filter')($rootScope.vaultCiphers, { favorite: true });
|
|
|
|
if (!$rootScope.vaultCollections || !$rootScope.vaultCollections.length) {
|
|
$scope.noFolderCiphers = $filter('filter')($rootScope.vaultCiphers, { folderId: null });
|
|
if ($scope.noFolderCiphers.length >= 100) {
|
|
$scope.noFolderCiphers = null;
|
|
}
|
|
|
|
if ($scope.noFolderCiphers && $rootScope.vaultFolders && $rootScope.vaultFolders.length &&
|
|
!$rootScope.vaultFolders[$rootScope.vaultFolders.length - 1].id) {
|
|
$rootScope.vaultFolders = $rootScope.vaultFolders.slice(0, $rootScope.vaultFolders.length - 1);
|
|
}
|
|
}
|
|
|
|
if ($scope.showGroupingCounts) {
|
|
var folderCounts = { 'none': 0 };
|
|
var collectionCounts = {};
|
|
|
|
decCiphers.forEach((cipher) => {
|
|
if (cipher.folderId) {
|
|
if (!folderCounts.hasOwnProperty(cipher.folderId)) {
|
|
folderCounts[cipher.folderId] = 0;
|
|
}
|
|
folderCounts[cipher.folderId]++;
|
|
}
|
|
else {
|
|
folderCounts.none++;
|
|
}
|
|
|
|
if (cipher.collectionIds) {
|
|
cipher.collectionIds.forEach((collectionId) => {
|
|
if (!collectionCounts.hasOwnProperty(collectionId)) {
|
|
collectionCounts[collectionId] = 0;
|
|
}
|
|
collectionCounts[collectionId]++;
|
|
});
|
|
}
|
|
});
|
|
|
|
$rootScope.vaultFolders.forEach((folder) => {
|
|
folder.itemCount = folderCounts[folder.id || 'none'] || 0;
|
|
});
|
|
|
|
$rootScope.vaultCollections.forEach((collection) => {
|
|
collection.itemCount = collectionCounts[collection.id] || 0;
|
|
});
|
|
}
|
|
|
|
if (!delayLoad) {
|
|
setScrollY();
|
|
}
|
|
});
|
|
}
|
|
|
|
$scope.searchText = null;
|
|
if (state.searchText || $stateParams.searchText) {
|
|
$scope.searchText = state.searchText || $stateParams.searchText;
|
|
}
|
|
|
|
$scope.searchCiphers = function () {
|
|
if (!$scope.searchText || $scope.searchText.length < 2) {
|
|
return;
|
|
}
|
|
|
|
return searchCipher;
|
|
};
|
|
|
|
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: 'vault'
|
|
});
|
|
};
|
|
|
|
$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: 'vault'
|
|
});
|
|
|
|
// clean up
|
|
cipher.cancelClick = false;
|
|
cipher.clicked = false;
|
|
}, 200);
|
|
};
|
|
|
|
$scope.launchWebsite = function (cipher) {
|
|
if (cipher.login && cipher.login.uri) {
|
|
$analytics.eventTrack('Launched Website');
|
|
BrowserApi.createNewTab(cipher.login.uri);
|
|
}
|
|
};
|
|
|
|
$scope.viewGrouping = function (grouping, folder) {
|
|
storeState();
|
|
$state.go('viewGrouping', {
|
|
folderId: (folder && grouping.id) || '0',
|
|
collectionId: (!folder && grouping.id) || '0',
|
|
animation: 'in-slide-left'
|
|
});
|
|
};
|
|
|
|
$scope.$on('syncCompleted', function (event, successfully) {
|
|
$timeout(loadVault, 500);
|
|
});
|
|
|
|
function storeState() {
|
|
stateService.saveState(stateKey, {
|
|
scrollY: getScrollY(),
|
|
searchText: $scope.searchText
|
|
});
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
});
|