mirror of
https://github.com/bitwarden/browser.git
synced 2024-12-25 16:59:17 +01:00
rename subvault => collection
This commit is contained in:
parent
361f03eb5f
commit
1ebae5c284
@ -82,11 +82,11 @@ angular
|
||||
refreshFromServer: false
|
||||
}
|
||||
})
|
||||
.state('backend.user.subvaults', {
|
||||
url: '^/subvaults',
|
||||
templateUrl: 'app/vault/views/vaultSubvaults.html',
|
||||
controller: 'vaultSubvaultsController',
|
||||
data: { pageTitle: 'Subvaults' }
|
||||
.state('backend.user.collections', {
|
||||
url: '^/collections',
|
||||
templateUrl: 'app/vault/views/vaultCollections.html',
|
||||
controller: 'vaultCollectionsController',
|
||||
data: { pageTitle: 'Collections' }
|
||||
})
|
||||
.state('backend.user.settings', {
|
||||
url: '^/settings',
|
||||
@ -134,11 +134,11 @@ angular
|
||||
controller: 'organizationPeopleController',
|
||||
data: { pageTitle: 'Organization People' }
|
||||
})
|
||||
.state('backend.org.subvaults', {
|
||||
url: '/organization/:orgId/subvaults',
|
||||
templateUrl: 'app/organization/views/organizationSubvaults.html',
|
||||
controller: 'organizationSubvaultsController',
|
||||
data: { pageTitle: 'Organization Subvaults' }
|
||||
.state('backend.org.collections', {
|
||||
url: '/organization/:orgId/collections',
|
||||
templateUrl: 'app/organization/views/organizationCollections.html',
|
||||
controller: 'organizationCollectionsController',
|
||||
data: { pageTitle: 'Organization Collections' }
|
||||
})
|
||||
.state('backend.org.settings', {
|
||||
url: '/organization/:orgId/settings',
|
||||
|
@ -94,7 +94,7 @@
|
||||
email: list.Data[i].Email,
|
||||
status: list.Data[i].Status,
|
||||
type: list.Data[i].Type,
|
||||
accessAllSubvaults: list.Data[i].AccessAllSubvaults
|
||||
accessAllCollections: list.Data[i].AccessAllCollections
|
||||
};
|
||||
|
||||
users.push(user);
|
||||
|
@ -6,88 +6,88 @@
|
||||
$analytics.eventTrack('organizationPeopleEditController', { category: 'Modal' });
|
||||
|
||||
$scope.loading = true;
|
||||
$scope.subvaults = [];
|
||||
$scope.selectedSubvaults = {};
|
||||
$scope.collections = [];
|
||||
$scope.selectedCollections = {};
|
||||
|
||||
$uibModalInstance.opened.then(function () {
|
||||
apiService.subvaults.listOrganization({ orgId: $state.params.orgId }, function (list) {
|
||||
$scope.subvaults = cipherService.decryptSubvaults(list.Data, $state.params.orgId, true);
|
||||
apiService.collections.listOrganization({ orgId: $state.params.orgId }, function (list) {
|
||||
$scope.collections = cipherService.decryptCollections(list.Data, $state.params.orgId, true);
|
||||
$scope.loading = false;
|
||||
});
|
||||
|
||||
apiService.organizationUsers.get({ orgId: $state.params.orgId, id: id }, function (user) {
|
||||
var subvaults = {};
|
||||
if (user && user.Subvaults) {
|
||||
for (var i = 0; i < user.Subvaults.Data.length; i++) {
|
||||
subvaults[user.Subvaults.Data[i].SubvaultId] = {
|
||||
subvaultId: user.Subvaults.Data[i].SubvaultId,
|
||||
readOnly: user.Subvaults.Data[i].ReadOnly
|
||||
var collections = {};
|
||||
if (user && user.Collections) {
|
||||
for (var i = 0; i < user.Collections.Data.length; i++) {
|
||||
collections[user.Collections.Data[i].CollectionId] = {
|
||||
collectionId: user.Collections.Data[i].CollectionId,
|
||||
readOnly: user.Collections.Data[i].ReadOnly
|
||||
};
|
||||
}
|
||||
}
|
||||
$scope.email = user.Email;
|
||||
$scope.type = user.Type;
|
||||
$scope.accessAllSubvaults = user.AccessAllSubvaults;
|
||||
$scope.selectedSubvaults = subvaults;
|
||||
$scope.accessAllCollections = user.AccessAllCollections;
|
||||
$scope.selectedCollections = collections;
|
||||
});
|
||||
});
|
||||
|
||||
$scope.toggleSubvaultSelectionAll = function ($event) {
|
||||
var subvaults = {};
|
||||
$scope.toggleCollectionSelectionAll = function ($event) {
|
||||
var collections = {};
|
||||
if ($event.target.checked) {
|
||||
for (var i = 0; i < $scope.subvaults.length; i++) {
|
||||
subvaults[$scope.subvaults[i].id] = {
|
||||
subvaultId: $scope.subvaults[i].id,
|
||||
readOnly: ($scope.subvaults[i].id in $scope.selectedSubvaults) ?
|
||||
$scope.selectedSubvaults[$scope.subvaults[i].id].readOnly : false
|
||||
for (var i = 0; i < $scope.collections.length; i++) {
|
||||
collections[$scope.collections[i].id] = {
|
||||
collectionId: $scope.collections[i].id,
|
||||
readOnly: ($scope.collections[i].id in $scope.selectedCollections) ?
|
||||
$scope.selectedCollections[$scope.collections[i].id].readOnly : false
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
$scope.selectedSubvaults = subvaults;
|
||||
$scope.selectedCollections = collections;
|
||||
};
|
||||
|
||||
$scope.toggleSubvaultSelection = function (id) {
|
||||
if (id in $scope.selectedSubvaults) {
|
||||
delete $scope.selectedSubvaults[id];
|
||||
$scope.toggleCollectionSelection = function (id) {
|
||||
if (id in $scope.selectedCollections) {
|
||||
delete $scope.selectedCollections[id];
|
||||
}
|
||||
else {
|
||||
$scope.selectedSubvaults[id] = {
|
||||
subvaultId: id,
|
||||
$scope.selectedCollections[id] = {
|
||||
collectionId: id,
|
||||
readOnly: false
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
$scope.toggleSubvaultReadOnlySelection = function (id) {
|
||||
if (id in $scope.selectedSubvaults) {
|
||||
$scope.selectedSubvaults[id].readOnly = !!!$scope.selectedSubvaults[id].readOnly;
|
||||
$scope.toggleCollectionReadOnlySelection = function (id) {
|
||||
if (id in $scope.selectedCollections) {
|
||||
$scope.selectedCollections[id].readOnly = !!!$scope.selectedCollections[id].readOnly;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.subvaultSelected = function (subvault) {
|
||||
return subvault.id in $scope.selectedSubvaults;
|
||||
$scope.collectionSelected = function (collection) {
|
||||
return collection.id in $scope.selectedCollections;
|
||||
};
|
||||
|
||||
$scope.allSelected = function () {
|
||||
return Object.keys($scope.selectedSubvaults).length === $scope.subvaults.length;
|
||||
return Object.keys($scope.selectedCollections).length === $scope.collections.length;
|
||||
};
|
||||
|
||||
$scope.submitPromise = null;
|
||||
$scope.submit = function (model) {
|
||||
var subvaults = [];
|
||||
if (!$scope.accessAllSubvaults) {
|
||||
for (var subvaultId in $scope.selectedSubvaults) {
|
||||
if ($scope.selectedSubvaults.hasOwnProperty(subvaultId)) {
|
||||
subvaults.push($scope.selectedSubvaults[subvaultId]);
|
||||
var collections = [];
|
||||
if (!$scope.accessAllCollections) {
|
||||
for (var collectionId in $scope.selectedCollections) {
|
||||
if ($scope.selectedCollections.hasOwnProperty(collectionId)) {
|
||||
collections.push($scope.selectedCollections[collectionId]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$scope.submitPromise = apiService.organizationUsers.put({ orgId: $state.params.orgId, id: id }, {
|
||||
type: $scope.type,
|
||||
subvaults: subvaults,
|
||||
accessAllSubvaults: $scope.accessAllSubvaults
|
||||
collections: collections,
|
||||
accessAllCollections: $scope.accessAllCollections
|
||||
}, function () {
|
||||
$analytics.eventTrack('Edited User');
|
||||
$uibModalInstance.close();
|
||||
|
@ -6,68 +6,68 @@
|
||||
$analytics.eventTrack('organizationPeopleInviteController', { category: 'Modal' });
|
||||
|
||||
$scope.loading = true;
|
||||
$scope.subvaults = [];
|
||||
$scope.selectedSubvaults = {};
|
||||
$scope.collections = [];
|
||||
$scope.selectedCollections = {};
|
||||
$scope.model = {
|
||||
type: 'User'
|
||||
};
|
||||
|
||||
$uibModalInstance.opened.then(function () {
|
||||
apiService.subvaults.listOrganization({ orgId: $state.params.orgId }, function (list) {
|
||||
$scope.subvaults = cipherService.decryptSubvaults(list.Data, $state.params.orgId, true);
|
||||
apiService.collections.listOrganization({ orgId: $state.params.orgId }, function (list) {
|
||||
$scope.collections = cipherService.decryptCollections(list.Data, $state.params.orgId, true);
|
||||
$scope.loading = false;
|
||||
});
|
||||
});
|
||||
|
||||
$scope.toggleSubvaultSelectionAll = function ($event) {
|
||||
var subvaults = {};
|
||||
$scope.toggleCollectionSelectionAll = function ($event) {
|
||||
var collections = {};
|
||||
if ($event.target.checked) {
|
||||
for (var i = 0; i < $scope.subvaults.length; i++) {
|
||||
subvaults[$scope.subvaults[i].id] = {
|
||||
subvaultId: $scope.subvaults[i].id,
|
||||
readOnly: ($scope.subvaults[i].id in $scope.selectedSubvaults) ?
|
||||
$scope.selectedSubvaults[$scope.subvaults[i].id].readOnly : false
|
||||
for (var i = 0; i < $scope.collections.length; i++) {
|
||||
collections[$scope.collections[i].id] = {
|
||||
collectionId: $scope.collections[i].id,
|
||||
readOnly: ($scope.collections[i].id in $scope.selectedCollections) ?
|
||||
$scope.selectedCollections[$scope.collections[i].id].readOnly : false
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
$scope.selectedSubvaults = subvaults;
|
||||
$scope.selectedCollections = collections;
|
||||
};
|
||||
|
||||
$scope.toggleSubvaultSelection = function (id) {
|
||||
if (id in $scope.selectedSubvaults) {
|
||||
delete $scope.selectedSubvaults[id];
|
||||
$scope.toggleCollectionSelection = function (id) {
|
||||
if (id in $scope.selectedCollections) {
|
||||
delete $scope.selectedCollections[id];
|
||||
}
|
||||
else {
|
||||
$scope.selectedSubvaults[id] = {
|
||||
subvaultId: id,
|
||||
$scope.selectedCollections[id] = {
|
||||
collectionId: id,
|
||||
readOnly: false
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
$scope.toggleSubvaultReadOnlySelection = function (id) {
|
||||
if (id in $scope.selectedSubvaults) {
|
||||
$scope.selectedSubvaults[id].readOnly = !!!$scope.selectedSubvaults[id].readOnly;
|
||||
$scope.toggleCollectionReadOnlySelection = function (id) {
|
||||
if (id in $scope.selectedCollections) {
|
||||
$scope.selectedCollections[id].readOnly = !!!$scope.selectedCollections[id].readOnly;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.subvaultSelected = function (subvault) {
|
||||
return subvault.id in $scope.selectedSubvaults;
|
||||
$scope.collectionSelected = function (collection) {
|
||||
return collection.id in $scope.selectedCollections;
|
||||
};
|
||||
|
||||
$scope.allSelected = function () {
|
||||
return Object.keys($scope.selectedSubvaults).length === $scope.subvaults.length;
|
||||
return Object.keys($scope.selectedCollections).length === $scope.collections.length;
|
||||
};
|
||||
|
||||
$scope.submitPromise = null;
|
||||
$scope.submit = function (model) {
|
||||
var subvaults = [];
|
||||
var collections = [];
|
||||
|
||||
if (!model.accessAllSubvaults) {
|
||||
for (var subvaultId in $scope.selectedSubvaults) {
|
||||
if ($scope.selectedSubvaults.hasOwnProperty(subvaultId)) {
|
||||
subvaults.push($scope.selectedSubvaults[subvaultId]);
|
||||
if (!model.accessAllCollections) {
|
||||
for (var collectionId in $scope.selectedCollections) {
|
||||
if ($scope.selectedCollections.hasOwnProperty(collectionId)) {
|
||||
collections.push($scope.selectedCollections[collectionId]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -75,8 +75,8 @@
|
||||
$scope.submitPromise = apiService.organizationUsers.invite({ orgId: $state.params.orgId }, {
|
||||
email: model.email,
|
||||
type: model.type,
|
||||
subvaults: subvaults,
|
||||
accessAllSubvaults: model.accessAllSubvaults
|
||||
collections: collections,
|
||||
accessAllCollections: model.accessAllCollections
|
||||
}, function () {
|
||||
$analytics.eventTrack('Invited User');
|
||||
$uibModalInstance.close();
|
||||
|
@ -1,16 +1,16 @@
|
||||
angular
|
||||
.module('bit.organization')
|
||||
|
||||
.controller('organizationSubvaultsAddController', function ($scope, $state, $uibModalInstance, apiService, cipherService,
|
||||
.controller('organizationCollectionsAddController', function ($scope, $state, $uibModalInstance, apiService, cipherService,
|
||||
$analytics) {
|
||||
$analytics.eventTrack('organizationSubvaultsAddController', { category: 'Modal' });
|
||||
$analytics.eventTrack('organizationCollectionsAddController', { category: 'Modal' });
|
||||
|
||||
$scope.submit = function (model) {
|
||||
var subvault = cipherService.encryptSubvault(model, $state.params.orgId);
|
||||
$scope.submitPromise = apiService.subvaults.post({ orgId: $state.params.orgId }, subvault, function (response) {
|
||||
$analytics.eventTrack('Created Subvault');
|
||||
var decSubvault = cipherService.decryptSubvault(response, $state.params.orgId, true);
|
||||
$uibModalInstance.close(decSubvault);
|
||||
var collection = cipherService.encryptCollection(model, $state.params.orgId);
|
||||
$scope.submitPromise = apiService.collections.post({ orgId: $state.params.orgId }, collection, function (response) {
|
||||
$analytics.eventTrack('Created Collection');
|
||||
var decCollection = cipherService.decryptCollection(response, $state.params.orgId, true);
|
||||
$uibModalInstance.close(decCollection);
|
||||
}).$promise;
|
||||
};
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
angular
|
||||
.module('bit.organization')
|
||||
|
||||
.controller('organizationSubvaultsController', function ($scope, $state, apiService, $uibModal, cipherService, $filter,
|
||||
.controller('organizationCollectionsController', function ($scope, $state, apiService, $uibModal, cipherService, $filter,
|
||||
toastr, $analytics) {
|
||||
$scope.subvaults = [];
|
||||
$scope.collections = [];
|
||||
$scope.loading = true;
|
||||
$scope.$on('$viewContentLoaded', function () {
|
||||
loadList();
|
||||
@ -12,41 +12,41 @@
|
||||
$scope.add = function () {
|
||||
var modal = $uibModal.open({
|
||||
animation: true,
|
||||
templateUrl: 'app/organization/views/organizationSubvaultsAdd.html',
|
||||
controller: 'organizationSubvaultsAddController'
|
||||
templateUrl: 'app/organization/views/organizationCollectionsAdd.html',
|
||||
controller: 'organizationCollectionsAddController'
|
||||
});
|
||||
|
||||
modal.result.then(function (subvault) {
|
||||
$scope.subvaults.push(subvault);
|
||||
modal.result.then(function (collection) {
|
||||
$scope.collections.push(collection);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.edit = function (subvault) {
|
||||
$scope.edit = function (collection) {
|
||||
var modal = $uibModal.open({
|
||||
animation: true,
|
||||
templateUrl: 'app/organization/views/organizationSubvaultsEdit.html',
|
||||
controller: 'organizationSubvaultsEditController',
|
||||
templateUrl: 'app/organization/views/organizationCollectionsEdit.html',
|
||||
controller: 'organizationCollectionsEditController',
|
||||
resolve: {
|
||||
id: function () { return subvault.id; }
|
||||
id: function () { return collection.id; }
|
||||
}
|
||||
});
|
||||
|
||||
modal.result.then(function (editedSubvault) {
|
||||
var existingSubvaults = $filter('filter')($scope.subvaults, { id: editedSubvault.id }, true);
|
||||
if (existingSubvaults && existingSubvaults.length > 0) {
|
||||
existingSubvaults[0].name = editedSubvault.name;
|
||||
modal.result.then(function (editedCollection) {
|
||||
var existingCollections = $filter('filter')($scope.collections, { id: editedCollection.id }, true);
|
||||
if (existingCollections && existingCollections.length > 0) {
|
||||
existingCollections[0].name = editedCollection.name;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$scope.users = function (subvault) {
|
||||
$scope.users = function (collection) {
|
||||
var modal = $uibModal.open({
|
||||
animation: true,
|
||||
templateUrl: 'app/organization/views/organizationSubvaultsUsers.html',
|
||||
controller: 'organizationSubvaultsUsersController',
|
||||
templateUrl: 'app/organization/views/organizationCollectionsUsers.html',
|
||||
controller: 'organizationCollectionsUsersController',
|
||||
size: 'lg',
|
||||
resolve: {
|
||||
subvault: function () { return subvault; }
|
||||
collection: function () { return collection; }
|
||||
}
|
||||
});
|
||||
|
||||
@ -55,13 +55,13 @@
|
||||
});
|
||||
};
|
||||
|
||||
$scope.groups = function (subvault) {
|
||||
$scope.groups = function (collection) {
|
||||
var modal = $uibModal.open({
|
||||
animation: true,
|
||||
templateUrl: 'app/organization/views/organizationSubvaultsGroups.html',
|
||||
controller: 'organizationSubvaultsGroupsController',
|
||||
templateUrl: 'app/organization/views/organizationCollectionsGroups.html',
|
||||
controller: 'organizationCollectionsGroupsController',
|
||||
resolve: {
|
||||
subvault: function () { return subvault; }
|
||||
collection: function () { return collection; }
|
||||
}
|
||||
});
|
||||
|
||||
@ -70,27 +70,27 @@
|
||||
});
|
||||
};
|
||||
|
||||
$scope.delete = function (subvault) {
|
||||
if (!confirm('Are you sure you want to delete this subvault (' + subvault.name + ')?')) {
|
||||
$scope.delete = function (collection) {
|
||||
if (!confirm('Are you sure you want to delete this collection (' + collection.name + ')?')) {
|
||||
return;
|
||||
}
|
||||
|
||||
apiService.subvaults.del({ orgId: $state.params.orgId, id: subvault.id }, function () {
|
||||
var index = $scope.subvaults.indexOf(subvault);
|
||||
apiService.collections.del({ orgId: $state.params.orgId, id: collection.id }, function () {
|
||||
var index = $scope.collections.indexOf(collection);
|
||||
if (index > -1) {
|
||||
$scope.subvaults.splice(index, 1);
|
||||
$scope.collections.splice(index, 1);
|
||||
}
|
||||
|
||||
$analytics.eventTrack('Deleted Subvault');
|
||||
toastr.success(subvault.name + ' has been deleted.', 'Subvault Deleted');
|
||||
$analytics.eventTrack('Deleted Collection');
|
||||
toastr.success(collection.name + ' has been deleted.', 'Collection Deleted');
|
||||
}, function () {
|
||||
toastr.error(subvault.name + ' was not able to be deleted.', 'Error');
|
||||
toastr.error(collection.name + ' was not able to be deleted.', 'Error');
|
||||
});
|
||||
};
|
||||
|
||||
function loadList() {
|
||||
apiService.subvaults.listOrganization({ orgId: $state.params.orgId }, function (list) {
|
||||
$scope.subvaults = cipherService.decryptSubvaults(list.Data, $state.params.orgId, true);
|
||||
apiService.collections.listOrganization({ orgId: $state.params.orgId }, function (list) {
|
||||
$scope.collections = cipherService.decryptCollections(list.Data, $state.params.orgId, true);
|
||||
$scope.loading = false;
|
||||
});
|
||||
}
|
||||
|
@ -1,23 +1,23 @@
|
||||
angular
|
||||
.module('bit.organization')
|
||||
|
||||
.controller('organizationSubvaultsEditController', function ($scope, $state, $uibModalInstance, apiService, cipherService,
|
||||
.controller('organizationCollectionsEditController', function ($scope, $state, $uibModalInstance, apiService, cipherService,
|
||||
$analytics, id) {
|
||||
$analytics.eventTrack('organizationSubvaultsEditController', { category: 'Modal' });
|
||||
$scope.subvault = {};
|
||||
$analytics.eventTrack('organizationCollectionsEditController', { category: 'Modal' });
|
||||
$scope.collection = {};
|
||||
|
||||
$uibModalInstance.opened.then(function () {
|
||||
apiService.subvaults.get({ orgId: $state.params.orgId, id: id }, function (subvault) {
|
||||
$scope.subvault = cipherService.decryptSubvault(subvault);
|
||||
apiService.collections.get({ orgId: $state.params.orgId, id: id }, function (collection) {
|
||||
$scope.collection = cipherService.decryptCollection(collection);
|
||||
});
|
||||
});
|
||||
|
||||
$scope.submit = function (model) {
|
||||
var subvault = cipherService.encryptSubvault(model, $state.params.orgId);
|
||||
$scope.submitPromise = apiService.subvaults.put({ orgId: $state.params.orgId }, subvault, function (response) {
|
||||
$analytics.eventTrack('Edited Subvault');
|
||||
var decSubvault = cipherService.decryptSubvault(response, $state.params.orgId, true);
|
||||
$uibModalInstance.close(decSubvault);
|
||||
var collection = cipherService.encryptCollection(model, $state.params.orgId);
|
||||
$scope.submitPromise = apiService.collections.put({ orgId: $state.params.orgId }, collection, function (response) {
|
||||
$analytics.eventTrack('Edited Collection');
|
||||
var decCollection = cipherService.decryptCollection(response, $state.params.orgId, true);
|
||||
$uibModalInstance.close(decCollection);
|
||||
}).$promise;
|
||||
};
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
angular
|
||||
.module('bit.organization')
|
||||
|
||||
.controller('organizationSubvaultsGroupsController', function ($scope, $state, $uibModalInstance, subvault, $analytics) {
|
||||
$analytics.eventTrack('organizationSubvaultsGroupsController', { category: 'Modal' });
|
||||
$scope.subvault = subvault;
|
||||
.controller('organizationCollectionsGroupsController', function ($scope, $state, $uibModalInstance, collection, $analytics) {
|
||||
$analytics.eventTrack('organizationCollectionsGroupsController', { category: 'Modal' });
|
||||
$scope.collection = collection;
|
||||
|
||||
$scope.close = function () {
|
||||
$uibModalInstance.dismiss('cancel');
|
||||
|
@ -1,19 +1,19 @@
|
||||
angular
|
||||
.module('bit.organization')
|
||||
|
||||
.controller('organizationSubvaultsUsersController', function ($scope, $state, $uibModalInstance, apiService, cipherService,
|
||||
$analytics, subvault, toastr) {
|
||||
$analytics.eventTrack('organizationSubvaultsUsersController', { category: 'Modal' });
|
||||
.controller('organizationCollectionsUsersController', function ($scope, $state, $uibModalInstance, apiService, cipherService,
|
||||
$analytics, collection, toastr) {
|
||||
$analytics.eventTrack('organizationCollectionsUsersController', { category: 'Modal' });
|
||||
$scope.loading = true;
|
||||
$scope.subvault = subvault;
|
||||
$scope.collection = collection;
|
||||
$scope.users = [];
|
||||
|
||||
$uibModalInstance.opened.then(function () {
|
||||
$scope.loading = false;
|
||||
apiService.subvaultUsers.listSubvault(
|
||||
apiService.collectionUsers.listCollection(
|
||||
{
|
||||
orgId: $state.params.orgId,
|
||||
subvaultId: subvault.id
|
||||
collectionId: collection.id
|
||||
},
|
||||
function (userList) {
|
||||
if (userList && userList.Data.length) {
|
||||
@ -27,7 +27,7 @@
|
||||
type: userList.Data[i].Type,
|
||||
status: userList.Data[i].Status,
|
||||
readOnly: userList.Data[i].ReadOnly,
|
||||
accessAllSubvaults: userList.Data[i].AccessAllSubvaults
|
||||
accessAllCollections: userList.Data[i].AccessAllCollections
|
||||
});
|
||||
}
|
||||
$scope.users = users;
|
||||
@ -37,13 +37,13 @@
|
||||
|
||||
$scope.remove = function (user) {
|
||||
if (!confirm('Are you sure you want to remove this user (' + user.email + ') from this ' +
|
||||
'subvault (' + subvault.name + ')?')) {
|
||||
'collection (' + collection.name + ')?')) {
|
||||
return;
|
||||
}
|
||||
|
||||
apiService.subvaultUsers.del({ orgId: $state.params.orgId, id: user.id }, null, function () {
|
||||
apiService.collectionUsers.del({ orgId: $state.params.orgId, id: user.id }, null, function () {
|
||||
toastr.success(user.email + ' has been removed.', 'User Removed');
|
||||
$analytics.eventTrack('Removed User From Subvault');
|
||||
$analytics.eventTrack('Removed User From Collection');
|
||||
var index = $scope.users.indexOf(user);
|
||||
if (index > -1) {
|
||||
$scope.users.splice(index, 1);
|
||||
|
@ -4,25 +4,25 @@
|
||||
.controller('organizationVaultController', function ($scope, apiService, cipherService, $analytics, $q, $state,
|
||||
$localStorage, $uibModal, $filter) {
|
||||
$scope.logins = [];
|
||||
$scope.subvaults = [];
|
||||
$scope.collections = [];
|
||||
$scope.loading = true;
|
||||
|
||||
$scope.$on('$viewContentLoaded', function () {
|
||||
var subvaultPromise = apiService.subvaults.listOrganization({ orgId: $state.params.orgId }, function (subvaults) {
|
||||
var decSubvaults = [{
|
||||
var collectionPromise = apiService.collections.listOrganization({ orgId: $state.params.orgId }, function (collections) {
|
||||
var decCollections = [{
|
||||
id: null,
|
||||
name: 'Unassigned',
|
||||
collapsed: $localStorage.collapsedOrgSubvaults && 'unassigned' in $localStorage.collapsedOrgSubvaults
|
||||
collapsed: $localStorage.collapsedOrgCollections && 'unassigned' in $localStorage.collapsedOrgCollections
|
||||
}];
|
||||
|
||||
for (var i = 0; i < subvaults.Data.length; i++) {
|
||||
var decSubvault = cipherService.decryptSubvault(subvaults.Data[i], null, true);
|
||||
decSubvault.collapsed = $localStorage.collapsedOrgSubvaults &&
|
||||
decSubvault.id in $localStorage.collapsedOrgSubvaults;
|
||||
decSubvaults.push(decSubvault);
|
||||
for (var i = 0; i < collections.Data.length; i++) {
|
||||
var decCollection = cipherService.decryptCollection(collections.Data[i], null, true);
|
||||
decCollection.collapsed = $localStorage.collapsedOrgCollections &&
|
||||
decCollection.id in $localStorage.collapsedOrgCollections;
|
||||
decCollections.push(decCollection);
|
||||
}
|
||||
|
||||
$scope.subvaults = decSubvaults;
|
||||
$scope.collections = decCollections;
|
||||
}).$promise;
|
||||
|
||||
var cipherPromise = apiService.ciphers.listOrganizationDetails({ organizationId: $state.params.orgId },
|
||||
@ -39,22 +39,22 @@
|
||||
$scope.logins = decLogins;
|
||||
}).$promise;
|
||||
|
||||
$q.all([subvaultPromise, cipherPromise]).then(function () {
|
||||
$q.all([collectionPromise, cipherPromise]).then(function () {
|
||||
$scope.loading = false;
|
||||
});
|
||||
});
|
||||
|
||||
$scope.filterBySubvault = function (subvault) {
|
||||
$scope.filterByCollection = function (collection) {
|
||||
return function (cipher) {
|
||||
if (!cipher.subvaultIds || !cipher.subvaultIds.length) {
|
||||
return subvault.id === null;
|
||||
if (!cipher.collectionIds || !cipher.collectionIds.length) {
|
||||
return collection.id === null;
|
||||
}
|
||||
|
||||
return cipher.subvaultIds.indexOf(subvault.id) > -1;
|
||||
return cipher.collectionIds.indexOf(collection.id) > -1;
|
||||
};
|
||||
};
|
||||
|
||||
$scope.subvaultSort = function (item) {
|
||||
$scope.collectionSort = function (item) {
|
||||
if (!item.id) {
|
||||
return '';
|
||||
}
|
||||
@ -62,58 +62,58 @@
|
||||
return item.name.toLowerCase();
|
||||
};
|
||||
|
||||
$scope.collapseExpand = function (subvault) {
|
||||
if (!$localStorage.collapsedOrgSubvaults) {
|
||||
$localStorage.collapsedOrgSubvaults = {};
|
||||
$scope.collapseExpand = function (collection) {
|
||||
if (!$localStorage.collapsedOrgCollections) {
|
||||
$localStorage.collapsedOrgCollections = {};
|
||||
}
|
||||
|
||||
var id = subvault.id || 'unassigned';
|
||||
var id = collection.id || 'unassigned';
|
||||
|
||||
if (id in $localStorage.collapsedOrgSubvaults) {
|
||||
delete $localStorage.collapsedOrgSubvaults[id];
|
||||
if (id in $localStorage.collapsedOrgCollections) {
|
||||
delete $localStorage.collapsedOrgCollections[id];
|
||||
}
|
||||
else {
|
||||
$localStorage.collapsedOrgSubvaults[id] = true;
|
||||
$localStorage.collapsedOrgCollections[id] = true;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.editSubvaults = function (cipher) {
|
||||
$scope.editCollections = function (cipher) {
|
||||
var modal = $uibModal.open({
|
||||
animation: true,
|
||||
templateUrl: 'app/organization/views/organizationVaultLoginSubvaults.html',
|
||||
controller: 'organizationVaultLoginSubvaultsController',
|
||||
templateUrl: 'app/organization/views/organizationVaultLoginCollections.html',
|
||||
controller: 'organizationVaultLoginCollectionsController',
|
||||
resolve: {
|
||||
cipher: function () { return cipher; },
|
||||
subvaults: function () { return $scope.subvaults; }
|
||||
collections: function () { return $scope.collections; }
|
||||
}
|
||||
});
|
||||
|
||||
modal.result.then(function (response) {
|
||||
if (response.subvaultIds) {
|
||||
cipher.subvaultIds = response.subvaultIds;
|
||||
if (response.collectionIds) {
|
||||
cipher.collectionIds = response.collectionIds;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$scope.removeLogin = function (login, subvault) {
|
||||
$scope.removeLogin = function (login, collection) {
|
||||
if (!confirm('Are you sure you want to remove this login (' + login.name + ') from the ' +
|
||||
'subvault (' + subvault.name + ') ?')) {
|
||||
'collection (' + collection.name + ') ?')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var request = {
|
||||
subvaultIds: []
|
||||
collectionIds: []
|
||||
};
|
||||
|
||||
for (var i = 0; i < login.subvaultIds.length; i++) {
|
||||
if (login.subvaultIds[i] !== subvault.id) {
|
||||
request.subvaultIds.push(login.subvaultIds[i]);
|
||||
for (var i = 0; i < login.collectionIds.length; i++) {
|
||||
if (login.collectionIds[i] !== collection.id) {
|
||||
request.collectionIds.push(login.collectionIds[i]);
|
||||
}
|
||||
}
|
||||
|
||||
apiService.ciphers.putSubvaults({ id: login.id }, request).$promise.then(function (response) {
|
||||
$analytics.eventTrack('Removed Login From Subvault');
|
||||
login.subvaultIds = request.subvaultIds;
|
||||
apiService.ciphers.putCollections({ id: login.id }, request).$promise.then(function (response) {
|
||||
$analytics.eventTrack('Removed Login From Collection');
|
||||
login.collectionIds = request.collectionIds;
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -1,78 +1,78 @@
|
||||
angular
|
||||
.module('bit.organization')
|
||||
|
||||
.controller('organizationVaultLoginSubvaultsController', function ($scope, apiService, $uibModalInstance, cipherService,
|
||||
cipher, $analytics, subvaults) {
|
||||
$analytics.eventTrack('organizationVaultLoginSubvaultsController', { category: 'Modal' });
|
||||
.controller('organizationVaultLoginCollectionsController', function ($scope, apiService, $uibModalInstance, cipherService,
|
||||
cipher, $analytics, collections) {
|
||||
$analytics.eventTrack('organizationVaultLoginCollectionsController', { category: 'Modal' });
|
||||
$scope.cipher = {};
|
||||
$scope.subvaults = [];
|
||||
$scope.selectedSubvaults = {};
|
||||
$scope.collections = [];
|
||||
$scope.selectedCollections = {};
|
||||
|
||||
$uibModalInstance.opened.then(function () {
|
||||
var subvaultUsed = [];
|
||||
for (var i = 0; i < subvaults.length; i++) {
|
||||
if (subvaults[i].id) {
|
||||
subvaultUsed.push(subvaults[i]);
|
||||
var collectionUsed = [];
|
||||
for (var i = 0; i < collections.length; i++) {
|
||||
if (collections[i].id) {
|
||||
collectionUsed.push(collections[i]);
|
||||
}
|
||||
}
|
||||
$scope.subvaults = subvaultUsed;
|
||||
$scope.collections = collectionUsed;
|
||||
|
||||
$scope.cipher = cipher;
|
||||
|
||||
var selectedSubvaults = {};
|
||||
if ($scope.cipher.subvaultIds) {
|
||||
for (i = 0; i < $scope.cipher.subvaultIds.length; i++) {
|
||||
selectedSubvaults[$scope.cipher.subvaultIds[i]] = true;
|
||||
var selectedCollections = {};
|
||||
if ($scope.cipher.collectionIds) {
|
||||
for (i = 0; i < $scope.cipher.collectionIds.length; i++) {
|
||||
selectedCollections[$scope.cipher.collectionIds[i]] = true;
|
||||
}
|
||||
}
|
||||
$scope.selectedSubvaults = selectedSubvaults;
|
||||
$scope.selectedCollections = selectedCollections;
|
||||
});
|
||||
|
||||
$scope.toggleSubvaultSelectionAll = function ($event) {
|
||||
var subvaults = {};
|
||||
$scope.toggleCollectionSelectionAll = function ($event) {
|
||||
var collections = {};
|
||||
if ($event.target.checked) {
|
||||
for (var i = 0; i < $scope.subvaults.length; i++) {
|
||||
subvaults[$scope.subvaults[i].id] = true;
|
||||
for (var i = 0; i < $scope.collections.length; i++) {
|
||||
collections[$scope.collections[i].id] = true;
|
||||
}
|
||||
}
|
||||
|
||||
$scope.selectedSubvaults = subvaults;
|
||||
$scope.selectedCollections = collections;
|
||||
};
|
||||
|
||||
$scope.toggleSubvaultSelection = function (id) {
|
||||
if (id in $scope.selectedSubvaults) {
|
||||
delete $scope.selectedSubvaults[id];
|
||||
$scope.toggleCollectionSelection = function (id) {
|
||||
if (id in $scope.selectedCollections) {
|
||||
delete $scope.selectedCollections[id];
|
||||
}
|
||||
else {
|
||||
$scope.selectedSubvaults[id] = true;
|
||||
$scope.selectedCollections[id] = true;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.subvaultSelected = function (subvault) {
|
||||
return subvault.id in $scope.selectedSubvaults;
|
||||
$scope.collectionSelected = function (collection) {
|
||||
return collection.id in $scope.selectedCollections;
|
||||
};
|
||||
|
||||
$scope.allSelected = function () {
|
||||
return Object.keys($scope.selectedSubvaults).length === $scope.subvaults.length;
|
||||
return Object.keys($scope.selectedCollections).length === $scope.collections.length;
|
||||
};
|
||||
|
||||
$scope.submit = function () {
|
||||
var request = {
|
||||
subvaultIds: []
|
||||
collectionIds: []
|
||||
};
|
||||
|
||||
for (var id in $scope.selectedSubvaults) {
|
||||
if ($scope.selectedSubvaults.hasOwnProperty(id)) {
|
||||
request.subvaultIds.push(id);
|
||||
for (var id in $scope.selectedCollections) {
|
||||
if ($scope.selectedCollections.hasOwnProperty(id)) {
|
||||
request.collectionIds.push(id);
|
||||
}
|
||||
}
|
||||
|
||||
$scope.submitPromise = apiService.ciphers.putSubvaultsAdmin({ id: cipher.id }, request)
|
||||
$scope.submitPromise = apiService.ciphers.putCollectionsAdmin({ id: cipher.id }, request)
|
||||
.$promise.then(function (response) {
|
||||
$analytics.eventTrack('Edited Login Subvaults');
|
||||
$analytics.eventTrack('Edited Login Collections');
|
||||
$uibModalInstance.close({
|
||||
action: 'subvaultsEdit',
|
||||
subvaultIds: request.subvaultIds
|
||||
action: 'collectionsEdit',
|
||||
collectionIds: request.collectionIds
|
||||
});
|
||||
});
|
||||
};
|
||||
|
@ -8,7 +8,7 @@
|
||||
<div class="callout callout-warning" ng-if="!orgProfile.enabled">
|
||||
<h4><i class="fa fa-warning"></i> Organization Disabled</h4>
|
||||
<p>
|
||||
This organization is currently disabled. Users will not see your shared logins or subvaults.
|
||||
This organization is currently disabled. Users will not see your shared logins or collections.
|
||||
Contact us if you would like to reinstate this organization.
|
||||
</p>
|
||||
<a class="btn btn-default btn-flat" href="https://bitwarden.com/contact/" target="_blank">
|
||||
@ -20,12 +20,12 @@
|
||||
<h3 class="box-title">Let's Get Started!</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<p>Dashboard features are coming soon. Get started by inviting users and creating your subvaults.</p>
|
||||
<p>Dashboard features are coming soon. Get started by inviting users and creating your collections.</p>
|
||||
<a class="btn btn-default btn-flat" ui-sref="backend.org.people({orgId: orgProfile.id})">
|
||||
Invite Users
|
||||
</a>
|
||||
<a class="btn btn-default btn-flat" ui-sref="backend.org.subvaults({orgId: orgProfile.id})">
|
||||
Manage Subvaults
|
||||
<a class="btn btn-default btn-flat" ui-sref="backend.org.collections({orgId: orgProfile.id})">
|
||||
Manage Collections
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<form name="form" ng-submit="form.$valid && submit()" api-form="submitPromise">
|
||||
<div class="modal-body">
|
||||
<p>
|
||||
Continue below to delete this organization and all associated data. This data includes any subvaults and
|
||||
Continue below to delete this organization and all associated data. This data includes any collections and
|
||||
their associated logins. Individual user accounts will remain, though they will not be associated to this
|
||||
organization anymore.
|
||||
</p>
|
||||
|
@ -64,8 +64,8 @@
|
||||
</td>
|
||||
<td>
|
||||
<a href="javascript:void(0)" ng-click="edit(user.id)">{{user.email}}</a>
|
||||
<i class="fa fa-share-alt text-muted" ng-show="user.accessAllSubvaults"
|
||||
title="Can Access All Subvaults"></i>
|
||||
<i class="fa fa-share-alt text-muted" ng-show="user.accessAllCollections"
|
||||
title="Can Access All Collections"></i>
|
||||
<div ng-if="user.name"><small class="text-muted">{{user.name}}</small></div>
|
||||
</td>
|
||||
<td style="width: 100px;">
|
||||
|
@ -15,13 +15,13 @@
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" id="user-type" ng-model="type" name="Type" value="2" ng-checked="type === 2">
|
||||
<strong>User</strong> - A regular user with access to your organization's subvaults.
|
||||
<strong>User</strong> - A regular user with access to your organization's collections.
|
||||
</label>
|
||||
</div>
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" ng-model="type" name="Type" value="1" ng-checked="type === 1">
|
||||
<strong>Admin</strong> - Admins can manage subvaults and users for your organization.
|
||||
<strong>Admin</strong> - Admins can manage collections and users for your organization.
|
||||
</label>
|
||||
</div>
|
||||
<div class="radio">
|
||||
@ -31,60 +31,60 @@
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<h4>Subvault Access</h4>
|
||||
<h4>Collection Access</h4>
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" ng-model="accessAllSubvaults" name="AccessAllSubvaults"
|
||||
ng-value="true" ng-checked="accessAllSubvaults">
|
||||
This user can access and modify items in <u>all</u> subvaults.
|
||||
<input type="radio" ng-model="accessAllCollections" name="AccessAllCollections"
|
||||
ng-value="true" ng-checked="accessAllCollections">
|
||||
This user can access and modify items in <u>all</u> collections.
|
||||
</label>
|
||||
</div>
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" ng-model="accessAllSubvaults" name="AccessAllSubvaults"
|
||||
ng-value="false" ng-checked="!accessAllSubvaults">
|
||||
This user can access only the selected subvaults.
|
||||
<input type="radio" ng-model="accessAllCollections" name="AccessAllCollections"
|
||||
ng-value="false" ng-checked="!accessAllCollections">
|
||||
This user can access only the selected collections.
|
||||
</label>
|
||||
</div>
|
||||
<div ng-show="!accessAllSubvaults">
|
||||
<div ng-show="loading && !subvaults.length">
|
||||
Loading subvaults...
|
||||
<div ng-show="!accessAllCollections">
|
||||
<div ng-show="loading && !collections.length">
|
||||
Loading collections...
|
||||
</div>
|
||||
<div ng-show="!loading && !subvaults.length">
|
||||
<p>No subvaults for your organization.</p>
|
||||
<div ng-show="!loading && !collections.length">
|
||||
<p>No collections for your organization.</p>
|
||||
</div>
|
||||
<div class="table-responsive" ng-show="subvaults.length" style="margin: 0;">
|
||||
<div class="table-responsive" ng-show="collections.length" style="margin: 0;">
|
||||
<table class="table table-striped table-hover" style="margin: 0;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 40px;">
|
||||
<input type="checkbox"
|
||||
ng-checked="allSelected()"
|
||||
ng-click="toggleSubvaultSelectionAll($event)">
|
||||
ng-click="toggleCollectionSelectionAll($event)">
|
||||
</th>
|
||||
<th>Name</th>
|
||||
<th style="width: 100px; text-align: center;">Read Only</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="subvault in subvaults | orderBy: ['name']">
|
||||
<tr ng-repeat="collection in collections | orderBy: ['name']">
|
||||
<td valign="middle">
|
||||
<input type="checkbox"
|
||||
name="selectedSubvaults[]"
|
||||
value="{{subvault.id}}"
|
||||
ng-checked="subvaultSelected(subvault)"
|
||||
ng-click="toggleSubvaultSelection(subvault.id)">
|
||||
name="selectedCollections[]"
|
||||
value="{{collection.id}}"
|
||||
ng-checked="collectionSelected(collection)"
|
||||
ng-click="toggleCollectionSelection(collection.id)">
|
||||
</td>
|
||||
<td valign="middle">
|
||||
{{subvault.name}}
|
||||
{{collection.name}}
|
||||
</td>
|
||||
<td style="text-align: center;" valign="middle">
|
||||
<input type="checkbox"
|
||||
name="selectedSubvaultsReadonly[]"
|
||||
value="{{subvault.id}}"
|
||||
ng-disabled="!subvaultSelected(subvault)"
|
||||
ng-checked="subvaultSelected(subvault) && selectedSubvaults[subvault.id].readOnly"
|
||||
ng-click="toggleSubvaultReadOnlySelection(subvault.id)">
|
||||
name="selectedCollectionsReadonly[]"
|
||||
value="{{collection.id}}"
|
||||
ng-disabled="!collectionSelected(collection)"
|
||||
ng-checked="collectionSelected(collection) && selectedCollections[collection.id].readOnly"
|
||||
ng-click="toggleCollectionReadOnlySelection(collection.id)">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@ -23,13 +23,13 @@
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" id="user-type" ng-model="model.type" name="Type" value="User">
|
||||
<strong>User</strong> - A regular user with access to your organization's subvaults.
|
||||
<strong>User</strong> - A regular user with access to your organization's collections.
|
||||
</label>
|
||||
</div>
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" ng-model="model.type" name="Type" value="Admin">
|
||||
<strong>Admin</strong> - Admins can manage subvaults and users for your organization.
|
||||
<strong>Admin</strong> - Admins can manage collections and users for your organization.
|
||||
</label>
|
||||
</div>
|
||||
<div class="radio">
|
||||
@ -39,60 +39,60 @@
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<h4>Subvault Access</h4>
|
||||
<h4>Collection Access</h4>
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" ng-model="model.accessAllSubvaults" name="AccessAllSubvaults"
|
||||
ng-value="true" ng-checked="model.accessAllSubvaults">
|
||||
This user can access and modify items in <u>all</u> subvaults.
|
||||
<input type="radio" ng-model="model.accessAllCollections" name="AccessAllCollections"
|
||||
ng-value="true" ng-checked="model.accessAllCollections">
|
||||
This user can access and modify items in <u>all</u> collections.
|
||||
</label>
|
||||
</div>
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" ng-model="model.accessAllSubvaults" name="AccessAllSubvaults"
|
||||
ng-value="false" ng-checked="!model.accessAllSubvaults">
|
||||
This user can access only the selected subvaults.
|
||||
<input type="radio" ng-model="model.accessAllCollections" name="AccessAllCollections"
|
||||
ng-value="false" ng-checked="!model.accessAllCollections">
|
||||
This user can access only the selected collections.
|
||||
</label>
|
||||
</div>
|
||||
<div ng-show="!model.accessAllSubvaults">
|
||||
<div ng-show="loading && !subvaults.length">
|
||||
Loading subvaults...
|
||||
<div ng-show="!model.accessAllCollections">
|
||||
<div ng-show="loading && !collections.length">
|
||||
Loading collections...
|
||||
</div>
|
||||
<div ng-show="!loading && !subvaults.length">
|
||||
<p>No subvaults for your organization.</p>
|
||||
<div ng-show="!loading && !collections.length">
|
||||
<p>No collections for your organization.</p>
|
||||
</div>
|
||||
<div class="table-responsive" ng-show="subvaults.length" style="margin: 0;">
|
||||
<div class="table-responsive" ng-show="collections.length" style="margin: 0;">
|
||||
<table class="table table-striped table-hover" style="margin: 0;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 40px;">
|
||||
<input type="checkbox"
|
||||
ng-checked="allSelected()"
|
||||
ng-click="toggleSubvaultSelectionAll($event)">
|
||||
ng-click="toggleCollectionSelectionAll($event)">
|
||||
</th>
|
||||
<th>Name</th>
|
||||
<th style="width: 100px; text-align: center;">Read Only</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="subvault in subvaults | orderBy: ['name'] track by subvault.id">
|
||||
<tr ng-repeat="collection in collections | orderBy: ['name'] track by collection.id">
|
||||
<td style="width: 40px;" valign="middle">
|
||||
<input type="checkbox"
|
||||
name="selectedSubvaults[]"
|
||||
value="{{subvault.id}}"
|
||||
ng-checked="subvaultSelected(subvault)"
|
||||
ng-click="toggleSubvaultSelection(subvault.id)">
|
||||
name="selectedCollections[]"
|
||||
value="{{collection.id}}"
|
||||
ng-checked="collectionSelected(collection)"
|
||||
ng-click="toggleCollectionSelection(collection.id)">
|
||||
</td>
|
||||
<td valign="middle">
|
||||
{{subvault.name}}
|
||||
{{collection.name}}
|
||||
</td>
|
||||
<td style="width: 100px; text-align: center;" valign="middle">
|
||||
<input type="checkbox"
|
||||
name="selectedSubvaultsReadonly[]"
|
||||
value="{{subvault.id}}"
|
||||
ng-disabled="!subvaultSelected(subvault)"
|
||||
ng-checked="subvaultSelected(subvault) && selectedSubvaults[subvault.id].readOnly"
|
||||
ng-click="toggleSubvaultReadOnlySelection(subvault.id)">
|
||||
name="selectedCollectionsReadonly[]"
|
||||
value="{{collection.id}}"
|
||||
ng-disabled="!collectionSelected(collection)"
|
||||
ng-checked="collectionSelected(collection) && selectedCollections[collection.id].readOnly"
|
||||
ng-click="toggleCollectionReadOnlySelection(collection.id)">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<section class="content-header">
|
||||
<h1>
|
||||
Subvaults
|
||||
Collections
|
||||
<small>share with your organization</small>
|
||||
</h1>
|
||||
</section>
|
||||
@ -10,33 +10,33 @@
|
||||
|
||||
<div class="box-filters hidden-xs">
|
||||
<div class="form-group form-group-sm has-feedback has-feedback-left">
|
||||
<input type="text" id="search" class="form-control" placeholder="Search subvaults..."
|
||||
<input type="text" id="search" class="form-control" placeholder="Search collections..."
|
||||
style="width: 200px;" ng-model="filterSearch">
|
||||
<span class="fa fa-search form-control-feedback text-muted" aria-hidden="true"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-tools">
|
||||
<button type="button" class="btn btn-primary btn-sm btn-flat" ng-click="add()">
|
||||
<i class="fa fa-fw fa-plus-circle"></i> New Subvault
|
||||
<i class="fa fa-fw fa-plus-circle"></i> New Collection
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body" ng-class="{'no-padding': filteredSubvaults.length}">
|
||||
<div ng-show="loading && !subvaults.length">
|
||||
<div class="box-body" ng-class="{'no-padding': filteredCollections.length}">
|
||||
<div ng-show="loading && !collections.length">
|
||||
Loading...
|
||||
</div>
|
||||
<div ng-show="!filteredSubvaults.length && filterSearch">
|
||||
No subvaults to list.
|
||||
<div ng-show="!filteredCollections.length && filterSearch">
|
||||
No collections to list.
|
||||
</div>
|
||||
<div ng-show="!loading && !subvaults.length">
|
||||
<p>There are no subvaults yet for your organization.</p>
|
||||
<button type="button" ng-click="add()" class="btn btn-default btn-flat">Add a Subvault</button>
|
||||
<div ng-show="!loading && !collections.length">
|
||||
<p>There are no collections yet for your organization.</p>
|
||||
<button type="button" ng-click="add()" class="btn btn-default btn-flat">Add a Collection</button>
|
||||
</div>
|
||||
<div class="table-responsive" ng-show="subvaults.length">
|
||||
<div class="table-responsive" ng-show="collections.length">
|
||||
<table class="table table-striped table-hover table-vmiddle">
|
||||
<tbody>
|
||||
<tr ng-repeat="subvault in filteredSubvaults = (subvaults | filter: (filterSearch || '') |
|
||||
orderBy: ['name']) track by subvault.id">
|
||||
<tr ng-repeat="collection in filteredCollections = (collections | filter: (filterSearch || '') |
|
||||
orderBy: ['name']) track by collection.id">
|
||||
<td style="width: 70px;">
|
||||
<div class="btn-group" data-append-to="body">
|
||||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
|
||||
@ -44,17 +44,17 @@
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
<a href="javascript:void(0)" ng-click="users(subvault)">
|
||||
<a href="javascript:void(0)" ng-click="users(collection)">
|
||||
<i class="fa fa-fw fa-users"></i> Users
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="javascript:void(0)" ng-click="groups(subvault)">
|
||||
<a href="javascript:void(0)" ng-click="groups(collection)">
|
||||
<i class="fa fa-fw fa-sitemap"></i> Groups
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="javascript:void(0)" ng-click="delete(subvault)" class="text-red">
|
||||
<a href="javascript:void(0)" ng-click="delete(collection)" class="text-red">
|
||||
<i class="fa fa-fw fa-trash"></i> Delete
|
||||
</a>
|
||||
</li>
|
||||
@ -62,8 +62,8 @@
|
||||
</div>
|
||||
</td>
|
||||
<td valign="middle">
|
||||
<a href="javascript:void(0)" ng-click="edit(subvault)">
|
||||
{{subvault.name}}
|
||||
<a href="javascript:void(0)" ng-click="edit(collection)">
|
||||
{{collection.name}}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" ng-click="close()" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title"><i class="fa fa-share-alt"></i> Add Subvault</h4>
|
||||
<h4 class="modal-title"><i class="fa fa-share-alt"></i> Add Collection</h4>
|
||||
</div>
|
||||
<form name="form" ng-submit="form.$valid && submit(model)" api-form="submitPromise">
|
||||
<div class="modal-body">
|
||||
@ -17,9 +17,9 @@
|
||||
<div class="callout callout-default">
|
||||
<h4><i class="fa fa-info-circle"></i> Note</h4>
|
||||
<p>
|
||||
After creating the subvault, you can associate a user to it by selecting a specific user on the "People" page.
|
||||
After creating the collection, you can associate a user to it by selecting a specific user on the "People" page.
|
||||
</p>
|
||||
<p>You can associate logins to the subvault by sharing from "My vault".</p>
|
||||
<p>You can associate logins to the collection by sharing from "My vault".</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
@ -1,8 +1,8 @@
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" ng-click="close()" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title"><i class="fa fa-share-alt"></i> Edit Subvault</h4>
|
||||
<h4 class="modal-title"><i class="fa fa-share-alt"></i> Edit Collection</h4>
|
||||
</div>
|
||||
<form name="form" ng-submit="form.$valid && submit(subvault)" api-form="submitPromise">
|
||||
<form name="form" ng-submit="form.$valid && submit(collection)" api-form="submitPromise">
|
||||
<div class="modal-body">
|
||||
<div class="callout callout-danger validation-errors" ng-show="form.$errors">
|
||||
<h4>Errors have occured</h4>
|
||||
@ -12,15 +12,15 @@
|
||||
</div>
|
||||
<div class="form-group" show-errors>
|
||||
<label for="email">Name</label>
|
||||
<input type="text" id="name" name="Name" ng-model="subvault.name" class="form-control" required api-field />
|
||||
<input type="text" id="name" name="Name" ng-model="collection.name" class="form-control" required api-field />
|
||||
</div>
|
||||
<div class="callout callout-default">
|
||||
<h4><i class="fa fa-info-circle"></i> Note</h4>
|
||||
<p>
|
||||
Select "Users" from the listing options to manage existing users for this subvault. Associate new users by
|
||||
managing the user's subvault access on the "People" page.
|
||||
Select "Users" from the listing options to manage existing users for this collection. Associate new users by
|
||||
managing the user's collection access on the "People" page.
|
||||
</p>
|
||||
<p>You can associate logins to this subvault by sharing from "My vault".</p>
|
||||
<p>You can associate logins to this collection by sharing from "My vault".</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
@ -1,6 +1,6 @@
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" ng-click="close()" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title"><i class="fa fa-sitemap"></i> Groups <small>{{subvault.name}}</small></h4>
|
||||
<h4 class="modal-title"><i class="fa fa-sitemap"></i> Groups <small>{{collection.name}}</small></h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
Groups are coming soon to bitwarden Enterprise organizations.
|
||||
|
@ -1,6 +1,6 @@
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" ng-click="close()" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title"><i class="fa fa-users"></i> User Access <small>{{subvault.name}}</small></h4>
|
||||
<h4 class="modal-title"><i class="fa fa-users"></i> User Access <small>{{collection.name}}</small></h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div ng-show="loading && !users.length">
|
||||
@ -8,7 +8,7 @@
|
||||
</div>
|
||||
<div ng-show="!loading && !users.length">
|
||||
<p>
|
||||
No users for this subvault. You can associate a new user to this subvault by
|
||||
No users for this collection. You can associate a new user to this collection by
|
||||
selecting a specific user on the "People" page.
|
||||
</p>
|
||||
</div>
|
||||
@ -43,7 +43,7 @@
|
||||
<div ng-if="user.name"><small class="text-muted">{{user.name}}</small></div>
|
||||
</td>
|
||||
<td style="width: 60px;" class="text-right">
|
||||
<i class="fa fa-share-alt" ng-show="user.accessAllSubvaults" title="Can Access All Subvaults"></i>
|
||||
<i class="fa fa-share-alt" ng-show="user.accessAllCollections" title="Can Access All Collections"></i>
|
||||
<i class="fa fa-pencil-square-o" ng-show="!user.readOnly" title="Can Edit"></i>
|
||||
</td>
|
||||
<td style="width: 100px;">
|
||||
|
@ -3,37 +3,37 @@
|
||||
Org<span class="hidden-xs">anization</span> Vault
|
||||
<small>
|
||||
<span ng-pluralize
|
||||
count="subvaults.length > 0 ? subvaults.length - 1 : 0"
|
||||
when="{'1': '{} subvault', 'other': '{} subvaults'}"></span>,
|
||||
count="collections.length > 0 ? collections.length - 1 : 0"
|
||||
when="{'1': '{} collection', 'other': '{} collections'}"></span>,
|
||||
<span ng-pluralize count="logins.length" when="{'1': '{} login', 'other': '{} logins'}"></span>
|
||||
</small>
|
||||
</h1>
|
||||
</section>
|
||||
<section class="content">
|
||||
<p ng-show="loading && !subvaults.length">Loading...</p>
|
||||
<div class="box" ng-class="{'collapsed-box': subvault.collapsed}" ng-repeat="subvault in subvaults |
|
||||
orderBy: subvaultSort track by subvault.id"
|
||||
ng-show="subvaults.length">
|
||||
<p ng-show="loading && !collections.length">Loading...</p>
|
||||
<div class="box" ng-class="{'collapsed-box': collection.collapsed}" ng-repeat="collection in collections |
|
||||
orderBy: collectionSort track by collection.id"
|
||||
ng-show="collections.length">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">
|
||||
<i class="fa" ng-class="{'fa-share-alt-square': subvault.id, 'fa-sitemap': !subvault.id}"></i>
|
||||
{{subvault.name}}
|
||||
<small ng-pluralize count="subvaultLogins.length" when="{'1': '{} login', 'other': '{} logins'}"></small>
|
||||
<i class="fa" ng-class="{'fa-share-alt-square': collection.id, 'fa-sitemap': !collection.id}"></i>
|
||||
{{collection.name}}
|
||||
<small ng-pluralize count="collectionLogins.length" when="{'1': '{} login', 'other': '{} logins'}"></small>
|
||||
</h3>
|
||||
<div class="box-tools">
|
||||
<button type="button" class="btn btn-box-tool" data-widget="collapse" title="Collapse/Expand"
|
||||
ng-click="collapseExpand(subvault)">
|
||||
<i class="fa" ng-class="{'fa-minus': !subvault.collapsed, 'fa-plus': subvault.collapsed}"></i>
|
||||
ng-click="collapseExpand(collection)">
|
||||
<i class="fa" ng-class="{'fa-minus': !collection.collapsed, 'fa-plus': collection.collapsed}"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body" ng-class="{'no-padding': subvaultLogins.length}">
|
||||
<div ng-show="!subvaultLogins.length && subvault.id">No logins in this subvault.</div>
|
||||
<div ng-show="!subvaultLogins.length && !subvault.id">No unassigned logins.</div>
|
||||
<div class="table-responsive" ng-show="subvaultLogins.length">
|
||||
<div class="box-body" ng-class="{'no-padding': collectionLogins.length}">
|
||||
<div ng-show="!collectionLogins.length && collection.id">No logins in this collection.</div>
|
||||
<div ng-show="!collectionLogins.length && !collection.id">No unassigned logins.</div>
|
||||
<div class="table-responsive" ng-show="collectionLogins.length">
|
||||
<table class="table table-striped table-hover table-vmiddle">
|
||||
<tbody>
|
||||
<tr ng-repeat="login in subvaultLogins = (logins | filter: filterBySubvault(subvault) |
|
||||
<tr ng-repeat="login in collectionLogins = (logins | filter: filterByCollection(collection) |
|
||||
orderBy: ['name', 'username']) track by login.id">
|
||||
<td style="width: 70px;">
|
||||
<div class="btn-group" data-append-to="body">
|
||||
@ -42,13 +42,13 @@
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
<a href="javascript:void(0)" ng-click="editSubvaults(login)">
|
||||
<i class="fa fa-fw fa-share-alt"></i> Subvaults
|
||||
<a href="javascript:void(0)" ng-click="editCollections(login)">
|
||||
<i class="fa fa-fw fa-share-alt"></i> Collections
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="javascript:void(0)" ng-click="removeLogin(login, subvault)" class="text-red"
|
||||
ng-if="subvault.id">
|
||||
<a href="javascript:void(0)" ng-click="removeLogin(login, collection)" class="text-red"
|
||||
ng-if="collection.id">
|
||||
<i class="fa fa-fw fa-remove"></i> Remove
|
||||
</a>
|
||||
</li>
|
||||
@ -61,7 +61,7 @@
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<a href="javascript:void(0)" ng-click="editSubvaults(login)">{{login.name}}</a>
|
||||
<a href="javascript:void(0)" ng-click="editCollections(login)">{{login.name}}</a>
|
||||
<div class="text-sm text-muted">{{login.username}}</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -1,42 +1,42 @@
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" ng-click="close()" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title"><i class="fa fa-share-alt"></i> Subvaults <small>{{cipher.name}}</small></h4>
|
||||
<h4 class="modal-title"><i class="fa fa-share-alt"></i> Collections <small>{{cipher.name}}</small></h4>
|
||||
</div>
|
||||
<form name="form" ng-submit="form.$valid && submit()" api-form="submitPromise">
|
||||
<div class="modal-body">
|
||||
<p>Edit the subvaults that this login is being shared with.</p>
|
||||
<p>Edit the collections that this login is being shared with.</p>
|
||||
<div class="callout callout-danger validation-errors" ng-show="form.$errors">
|
||||
<h4>Errors have occured</h4>
|
||||
<ul>
|
||||
<li ng-repeat="e in form.$errors">{{e}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div ng-show="!subvaults.length" class="callout callout-default">
|
||||
<p>No subvaults to manage.</p>
|
||||
<div ng-show="!collections.length" class="callout callout-default">
|
||||
<p>No collections to manage.</p>
|
||||
</div>
|
||||
<div class="table-responsive" ng-show="subvaults.length" style="margin: 0;">
|
||||
<div class="table-responsive" ng-show="collections.length" style="margin: 0;">
|
||||
<table class="table table-striped table-hover" style="margin: 0;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 40px;">
|
||||
<input type="checkbox"
|
||||
ng-checked="allSelected()"
|
||||
ng-click="toggleSubvaultSelectionAll($event)">
|
||||
ng-click="toggleCollectionSelectionAll($event)">
|
||||
</th>
|
||||
<th>Name</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="subvault in subvaults | orderBy: ['name'] track by subvault.id">
|
||||
<tr ng-repeat="collection in collections | orderBy: ['name'] track by collection.id">
|
||||
<td valign="middle">
|
||||
<input type="checkbox"
|
||||
name="selectedSubvaults[]"
|
||||
value="{{subvault.id}}"
|
||||
ng-checked="subvaultSelected(subvault)"
|
||||
ng-click="toggleSubvaultSelection(subvault.id)">
|
||||
name="selectedCollections[]"
|
||||
value="{{collection.id}}"
|
||||
ng-checked="collectionSelected(collection)"
|
||||
ng-click="toggleCollectionSelection(collection.id)">
|
||||
</td>
|
||||
<td valign="middle" ng-click="toggleSubvaultSelection(subvault.id)">
|
||||
{{subvault.name}}
|
||||
<td valign="middle" ng-click="toggleCollectionSelection(collection.id)">
|
||||
{{collection.name}}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@ -44,7 +44,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" class="btn btn-primary btn-flat" ng-disabled="form.$loading" ng-show="subvaults.length">
|
||||
<button type="submit" class="btn btn-primary btn-flat" ng-disabled="form.$loading" ng-show="collections.length">
|
||||
<i class="fa fa-refresh fa-spin loading-icon" ng-show="form.$loading"></i>Save
|
||||
</button>
|
||||
<button type="button" class="btn btn-default btn-flat" ng-click="close()">Close</button>
|
||||
|
@ -31,8 +31,8 @@
|
||||
favorite: { url: _apiUri + '/ciphers/:id/favorite', method: 'POST', params: { id: '@id' } },
|
||||
putPartial: { url: _apiUri + '/ciphers/:id/partial', method: 'POST', params: { id: '@id' } },
|
||||
putShare: { url: _apiUri + '/ciphers/:id/share', method: 'POST', params: { id: '@id' } },
|
||||
putSubvaults: { url: _apiUri + '/ciphers/:id/subvaults', method: 'POST', params: { id: '@id' } },
|
||||
putSubvaultsAdmin: { url: _apiUri + '/ciphers/:id/subvaults-admin', method: 'POST', params: { id: '@id' } },
|
||||
putCollections: { url: _apiUri + '/ciphers/:id/collections', method: 'POST', params: { id: '@id' } },
|
||||
putCollectionsAdmin: { url: _apiUri + '/ciphers/:id/collections-admin', method: 'POST', params: { id: '@id' } },
|
||||
del: { url: _apiUri + '/ciphers/:id/delete', method: 'POST', params: { id: '@id' } },
|
||||
delAdmin: { url: _apiUri + '/ciphers/:id/delete-admin', method: 'POST', params: { id: '@id' } }
|
||||
});
|
||||
@ -63,18 +63,18 @@
|
||||
del: { url: _apiUri + '/organizations/:orgId/users/:id/delete', method: 'POST', params: { id: '@id', orgId: '@orgId' } }
|
||||
});
|
||||
|
||||
_service.subvaults = $resource(_apiUri + '/organizations/:orgId/subvaults/:id', {}, {
|
||||
_service.collections = $resource(_apiUri + '/organizations/:orgId/collections/:id', {}, {
|
||||
get: { method: 'GET', params: { id: '@id', orgId: '@orgId' } },
|
||||
listMe: { url: _apiUri + '/subvaults', method: 'GET', params: {} },
|
||||
listMe: { url: _apiUri + '/collections', method: 'GET', params: {} },
|
||||
listOrganization: { method: 'GET', params: { orgId: '@orgId' } },
|
||||
post: { method: 'POST', params: { orgId: '@orgId' } },
|
||||
put: { method: 'POST', params: { id: '@id', orgId: '@orgId' } },
|
||||
del: { url: _apiUri + '/organizations/:orgId/subvaults/:id/delete', method: 'POST', params: { id: '@id', orgId: '@orgId' } }
|
||||
del: { url: _apiUri + '/organizations/:orgId/collections/:id/delete', method: 'POST', params: { id: '@id', orgId: '@orgId' } }
|
||||
});
|
||||
|
||||
_service.subvaultUsers = $resource(_apiUri + '/organizations/:orgId/subvaultUsers/:id', {}, {
|
||||
listSubvault: { url: _apiUri + '/organizations/:orgId/subvaultUsers/:subvaultId', method: 'GET', params: { subvaultId: '@subvaultId', orgId: '@orgId' } },
|
||||
del: { url: _apiUri + '/organizations/:orgId/subvaultUsers/:id/delete', method: 'POST', params: { id: '@id', orgId: '@orgId' } }
|
||||
_service.collectionUsers = $resource(_apiUri + '/organizations/:orgId/collectionUsers/:id', {}, {
|
||||
listCollection: { url: _apiUri + '/organizations/:orgId/collectionUsers/:collectionId', method: 'GET', params: { collectionId: '@collectionId', orgId: '@orgId' } },
|
||||
del: { url: _apiUri + '/organizations/:orgId/collectionUsers/:id/delete', method: 'POST', params: { id: '@id', orgId: '@orgId' } }
|
||||
});
|
||||
|
||||
_service.accounts = $resource(_apiUri + '/accounts', {}, {
|
||||
|
@ -26,7 +26,7 @@ angular
|
||||
var login = {
|
||||
id: encryptedLogin.Id,
|
||||
organizationId: encryptedLogin.OrganizationId,
|
||||
subvaultIds: encryptedLogin.SubvaultIds || [],
|
||||
collectionIds: encryptedLogin.CollectionIds || [],
|
||||
'type': 1,
|
||||
folderId: encryptedLogin.FolderId,
|
||||
favorite: encryptedLogin.Favorite,
|
||||
@ -51,7 +51,7 @@ angular
|
||||
var login = {
|
||||
id: encryptedCipher.Id,
|
||||
organizationId: encryptedCipher.OrganizationId,
|
||||
subvaultIds: encryptedCipher.SubvaultIds || [],
|
||||
collectionIds: encryptedCipher.CollectionIds || [],
|
||||
folderId: encryptedCipher.FolderId,
|
||||
favorite: encryptedCipher.Favorite,
|
||||
name: _service.decryptProperty(encryptedCipher.Data.Name, key, false),
|
||||
@ -90,28 +90,28 @@ angular
|
||||
};
|
||||
};
|
||||
|
||||
_service.decryptSubvaults = function (encryptedSubvaults, orgId, catchError) {
|
||||
if (!encryptedSubvaults) throw "encryptedSubvaults is undefined or null";
|
||||
_service.decryptCollections = function (encryptedCollections, orgId, catchError) {
|
||||
if (!encryptedCollections) throw "encryptedCollections is undefined or null";
|
||||
|
||||
var unencryptedSubvaults = [];
|
||||
for (var i = 0; i < encryptedSubvaults.length; i++) {
|
||||
unencryptedSubvaults.push(_service.decryptSubvault(encryptedSubvaults[i], orgId, catchError));
|
||||
var unencryptedCollections = [];
|
||||
for (var i = 0; i < encryptedCollections.length; i++) {
|
||||
unencryptedCollections.push(_service.decryptCollection(encryptedCollections[i], orgId, catchError));
|
||||
}
|
||||
|
||||
return unencryptedSubvaults;
|
||||
return unencryptedCollections;
|
||||
};
|
||||
|
||||
_service.decryptSubvault = function (encryptedSubvault, orgId, catchError) {
|
||||
if (!encryptedSubvault) throw "encryptedSubvault is undefined or null";
|
||||
_service.decryptCollection = function (encryptedCollection, orgId, catchError) {
|
||||
if (!encryptedCollection) throw "encryptedCollection is undefined or null";
|
||||
|
||||
catchError = catchError === true ? true : false;
|
||||
orgId = orgId || encryptedSubvault.OrganizationId;
|
||||
orgId = orgId || encryptedCollection.OrganizationId;
|
||||
var key = cryptoService.getOrgKey(orgId);
|
||||
|
||||
return {
|
||||
id: encryptedSubvault.Id,
|
||||
name: catchError ? _service.decryptProperty(encryptedSubvault.Name, key, false) :
|
||||
cryptoService.decrypt(encryptedSubvault.Name, key)
|
||||
id: encryptedCollection.Id,
|
||||
name: catchError ? _service.decryptProperty(encryptedCollection.Name, key, false) :
|
||||
cryptoService.decrypt(encryptedCollection.Name, key)
|
||||
};
|
||||
};
|
||||
|
||||
@ -182,23 +182,23 @@ angular
|
||||
};
|
||||
};
|
||||
|
||||
_service.encryptSubvaults = function (unencryptedSubvaults, orgId) {
|
||||
if (!unencryptedSubvaults) throw "unencryptedSubvaults is undefined or null";
|
||||
_service.encryptCollections = function (unencryptedCollections, orgId) {
|
||||
if (!unencryptedCollections) throw "unencryptedCollections is undefined or null";
|
||||
|
||||
var encryptedSubvaults = [];
|
||||
for (var i = 0; i < unencryptedSubvaults.length; i++) {
|
||||
encryptedSubvaults.push(_service.encryptSubvault(unencryptedSubvaults[i], orgId));
|
||||
var encryptedCollections = [];
|
||||
for (var i = 0; i < unencryptedCollections.length; i++) {
|
||||
encryptedCollections.push(_service.encryptCollection(unencryptedCollections[i], orgId));
|
||||
}
|
||||
|
||||
return encryptedSubvaults;
|
||||
return encryptedCollections;
|
||||
};
|
||||
|
||||
_service.encryptSubvault = function (unencryptedSubvault, orgId) {
|
||||
if (!unencryptedSubvault) throw "unencryptedSubvault is undefined or null";
|
||||
_service.encryptCollection = function (unencryptedCollection, orgId) {
|
||||
if (!unencryptedCollection) throw "unencryptedCollection is undefined or null";
|
||||
|
||||
return {
|
||||
id: unencryptedSubvault.id,
|
||||
name: cryptoService.encrypt(unencryptedSubvault.name, cryptoService.getOrgKey(orgId))
|
||||
id: unencryptedCollection.id,
|
||||
name: cryptoService.encrypt(unencryptedCollection.name, cryptoService.getOrgKey(orgId))
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -62,7 +62,7 @@
|
||||
Free
|
||||
<span>For personal users to share with 1 other user.</span>
|
||||
<span>- Limit 2 users (including you)</span>
|
||||
<span>- Limit 2 subvaults</span>
|
||||
<span>- Limit 2 collections</span>
|
||||
<span class="bottom-line">
|
||||
Free forever
|
||||
</span>
|
||||
@ -74,7 +74,7 @@
|
||||
Personal
|
||||
<span>For personal users such as families & friends.</span>
|
||||
<span>- Add and share with up to 10 users (5 included with base price)</span>
|
||||
<span>- Create unlimited subvaults</span>
|
||||
<span>- Create unlimited collections</span>
|
||||
<span>- Priority customer support</span>
|
||||
<span>- 7 day free trial, cancel anytime</span>
|
||||
<span class="bottom-line">
|
||||
@ -89,7 +89,7 @@
|
||||
Teams
|
||||
<span>For businesses and other team organizations.</span>
|
||||
<span>- Add and share with unlimited users</span>
|
||||
<span>- Create unlimited subvaults</span>
|
||||
<span>- Create unlimited collections</span>
|
||||
<span>- Priority customer support</span>
|
||||
<span>- 7 day free trial, cancel anytime</span>
|
||||
<span class="bottom-line">
|
||||
|
@ -264,18 +264,18 @@
|
||||
});
|
||||
};
|
||||
|
||||
$scope.subvaults = function (login) {
|
||||
$scope.collections = function (login) {
|
||||
var modal = $uibModal.open({
|
||||
animation: true,
|
||||
templateUrl: 'app/vault/views/vaultLoginSubvaults.html',
|
||||
controller: 'vaultLoginSubvaultsController',
|
||||
templateUrl: 'app/vault/views/vaultLoginCollections.html',
|
||||
controller: 'vaultLoginCollectionsController',
|
||||
resolve: {
|
||||
loginId: function () { return login.id; }
|
||||
}
|
||||
});
|
||||
|
||||
modal.result.then(function (response) {
|
||||
if (response.subvaultIds && !response.subvaultIds.length) {
|
||||
if (response.collectionIds && !response.collectionIds.length) {
|
||||
removeLoginFromScopes(login);
|
||||
}
|
||||
});
|
||||
|
@ -1,15 +1,15 @@
|
||||
angular
|
||||
.module('bit.vault')
|
||||
|
||||
.controller('vaultLoginSubvaultsController', function ($scope, apiService, $uibModalInstance, cipherService,
|
||||
.controller('vaultLoginCollectionsController', function ($scope, apiService, $uibModalInstance, cipherService,
|
||||
loginId, $analytics) {
|
||||
$analytics.eventTrack('vaultLoginSubvaultsController', { category: 'Modal' });
|
||||
$analytics.eventTrack('vaultLoginCollectionsController', { category: 'Modal' });
|
||||
$scope.login = {};
|
||||
$scope.readOnly = false;
|
||||
$scope.loadingLogin = true;
|
||||
$scope.loadingSubvaults = true;
|
||||
$scope.selectedSubvaults = {};
|
||||
$scope.subvaults = [];
|
||||
$scope.loadingCollections = true;
|
||||
$scope.selectedCollections = {};
|
||||
$scope.collections = [];
|
||||
|
||||
$uibModalInstance.opened.then(function () {
|
||||
apiService.ciphers.getFullDetails({ id: loginId }).$promise.then(function (cipher) {
|
||||
@ -21,13 +21,13 @@
|
||||
$scope.login = cipherService.decryptLoginPreview(cipher);
|
||||
}
|
||||
|
||||
var subvaults = {};
|
||||
if (cipher.SubvaultIds) {
|
||||
for (var i = 0; i < cipher.SubvaultIds.length; i++) {
|
||||
subvaults[cipher.SubvaultIds[i]] = true;
|
||||
var collections = {};
|
||||
if (cipher.CollectionIds) {
|
||||
for (var i = 0; i < cipher.CollectionIds.length; i++) {
|
||||
collections[cipher.CollectionIds[i]] = true;
|
||||
}
|
||||
}
|
||||
$scope.selectedSubvaults = subvaults;
|
||||
$scope.selectedCollections = collections;
|
||||
|
||||
return cipher;
|
||||
}
|
||||
@ -35,72 +35,72 @@
|
||||
return null;
|
||||
}).then(function (cipher) {
|
||||
if (!cipher) {
|
||||
$scope.loadingSubvaults = false;
|
||||
$scope.loadingCollections = false;
|
||||
return;
|
||||
}
|
||||
|
||||
apiService.subvaults.listMe(function (response) {
|
||||
var subvaults = [];
|
||||
apiService.collections.listMe(function (response) {
|
||||
var collections = [];
|
||||
for (var i = 0; i < response.Data.length; i++) {
|
||||
if (response.Data[i].OrganizationId !== cipher.OrganizationId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var decSubvault = cipherService.decryptSubvault(response.Data[i]);
|
||||
subvaults.push(decSubvault);
|
||||
var decCollection = cipherService.decryptCollection(response.Data[i]);
|
||||
collections.push(decCollection);
|
||||
}
|
||||
|
||||
$scope.loadingSubvaults = false;
|
||||
$scope.subvaults = subvaults;
|
||||
$scope.loadingCollections = false;
|
||||
$scope.collections = collections;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
$scope.toggleSubvaultSelectionAll = function ($event) {
|
||||
var subvaults = {};
|
||||
$scope.toggleCollectionSelectionAll = function ($event) {
|
||||
var collections = {};
|
||||
if ($event.target.checked) {
|
||||
for (var i = 0; i < $scope.subvaults.length; i++) {
|
||||
subvaults[$scope.subvaults[i].id] = true;
|
||||
for (var i = 0; i < $scope.collections.length; i++) {
|
||||
collections[$scope.collections[i].id] = true;
|
||||
}
|
||||
}
|
||||
|
||||
$scope.selectedSubvaults = subvaults;
|
||||
$scope.selectedCollections = collections;
|
||||
};
|
||||
|
||||
$scope.toggleSubvaultSelection = function (id) {
|
||||
if (id in $scope.selectedSubvaults) {
|
||||
delete $scope.selectedSubvaults[id];
|
||||
$scope.toggleCollectionSelection = function (id) {
|
||||
if (id in $scope.selectedCollections) {
|
||||
delete $scope.selectedCollections[id];
|
||||
}
|
||||
else {
|
||||
$scope.selectedSubvaults[id] = true;
|
||||
$scope.selectedCollections[id] = true;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.subvaultSelected = function (subvault) {
|
||||
return subvault.id in $scope.selectedSubvaults;
|
||||
$scope.collectionSelected = function (collection) {
|
||||
return collection.id in $scope.selectedCollections;
|
||||
};
|
||||
|
||||
$scope.allSelected = function () {
|
||||
return Object.keys($scope.selectedSubvaults).length === $scope.subvaults.length;
|
||||
return Object.keys($scope.selectedCollections).length === $scope.collections.length;
|
||||
};
|
||||
|
||||
$scope.submit = function () {
|
||||
var request = {
|
||||
subvaultIds: []
|
||||
collectionIds: []
|
||||
};
|
||||
|
||||
for (var id in $scope.selectedSubvaults) {
|
||||
if ($scope.selectedSubvaults.hasOwnProperty(id)) {
|
||||
request.subvaultIds.push(id);
|
||||
for (var id in $scope.selectedCollections) {
|
||||
if ($scope.selectedCollections.hasOwnProperty(id)) {
|
||||
request.collectionIds.push(id);
|
||||
}
|
||||
}
|
||||
|
||||
$scope.submitPromise = apiService.ciphers.putSubvaults({ id: loginId }, request)
|
||||
$scope.submitPromise = apiService.ciphers.putCollections({ id: loginId }, request)
|
||||
.$promise.then(function (response) {
|
||||
$analytics.eventTrack('Edited Login Subvaults');
|
||||
$analytics.eventTrack('Edited Login Collections');
|
||||
$uibModalInstance.close({
|
||||
action: 'subvaultsEdit',
|
||||
subvaultIds: request.subvaultIds
|
||||
action: 'collectionsEdit',
|
||||
collectionIds: request.collectionIds
|
||||
});
|
||||
});
|
||||
};
|
||||
|
@ -6,11 +6,11 @@
|
||||
$analytics.eventTrack('vaultShareController', { category: 'Modal' });
|
||||
$scope.model = {};
|
||||
$scope.login = {};
|
||||
$scope.subvaults = [];
|
||||
$scope.selectedSubvaults = {};
|
||||
$scope.collections = [];
|
||||
$scope.selectedCollections = {};
|
||||
$scope.organizations = [];
|
||||
var organizationSubvaultCounts = {};
|
||||
$scope.loadingSubvaults = true;
|
||||
var organizationCollectionCounts = {};
|
||||
$scope.loadingCollections = true;
|
||||
$scope.readOnly = false;
|
||||
|
||||
apiService.logins.get({ id: loginId }).$promise.then(function (login) {
|
||||
@ -38,7 +38,7 @@
|
||||
name: profile.organizations[i].name
|
||||
});
|
||||
|
||||
organizationSubvaultCounts[profile.organizations[i].id] = 0;
|
||||
organizationCollectionCounts[profile.organizations[i].id] = 0;
|
||||
|
||||
if (!setFirstOrg) {
|
||||
setFirstOrg = true;
|
||||
@ -49,45 +49,45 @@
|
||||
|
||||
$scope.organizations = orgs;
|
||||
|
||||
apiService.subvaults.listMe(function (response) {
|
||||
var subvaults = [];
|
||||
apiService.collections.listMe(function (response) {
|
||||
var collections = [];
|
||||
for (var i = 0; i < response.Data.length; i++) {
|
||||
var decSubvault = cipherService.decryptSubvault(response.Data[i]);
|
||||
decSubvault.organizationId = response.Data[i].OrganizationId;
|
||||
subvaults.push(decSubvault);
|
||||
organizationSubvaultCounts[decSubvault.organizationId]++;
|
||||
var decCollection = cipherService.decryptCollection(response.Data[i]);
|
||||
decCollection.organizationId = response.Data[i].OrganizationId;
|
||||
collections.push(decCollection);
|
||||
organizationCollectionCounts[decCollection.organizationId]++;
|
||||
}
|
||||
|
||||
$scope.subvaults = subvaults;
|
||||
$scope.loadingSubvaults = false;
|
||||
$scope.collections = collections;
|
||||
$scope.loadingCollections = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$scope.toggleSubvaultSelectionAll = function ($event) {
|
||||
var subvaults = {};
|
||||
$scope.toggleCollectionSelectionAll = function ($event) {
|
||||
var collections = {};
|
||||
if ($event.target.checked) {
|
||||
for (var i = 0; i < $scope.subvaults.length; i++) {
|
||||
if ($scope.model.organizationId && $scope.subvaults[i].organizationId === $scope.model.organizationId) {
|
||||
subvaults[$scope.subvaults[i].id] = true;
|
||||
for (var i = 0; i < $scope.collections.length; i++) {
|
||||
if ($scope.model.organizationId && $scope.collections[i].organizationId === $scope.model.organizationId) {
|
||||
collections[$scope.collections[i].id] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$scope.selectedSubvaults = subvaults;
|
||||
$scope.selectedCollections = collections;
|
||||
};
|
||||
|
||||
$scope.toggleSubvaultSelection = function (id) {
|
||||
if (id in $scope.selectedSubvaults) {
|
||||
delete $scope.selectedSubvaults[id];
|
||||
$scope.toggleCollectionSelection = function (id) {
|
||||
if (id in $scope.selectedCollections) {
|
||||
delete $scope.selectedCollections[id];
|
||||
}
|
||||
else {
|
||||
$scope.selectedSubvaults[id] = true;
|
||||
$scope.selectedCollections[id] = true;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.subvaultSelected = function (subvault) {
|
||||
return subvault.id in $scope.selectedSubvaults;
|
||||
$scope.collectionSelected = function (collection) {
|
||||
return collection.id in $scope.selectedCollections;
|
||||
};
|
||||
|
||||
$scope.allSelected = function () {
|
||||
@ -95,11 +95,11 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
return Object.keys($scope.selectedSubvaults).length === organizationSubvaultCounts[$scope.model.organizationId];
|
||||
return Object.keys($scope.selectedCollections).length === organizationCollectionCounts[$scope.model.organizationId];
|
||||
};
|
||||
|
||||
$scope.orgChanged = function () {
|
||||
$scope.selectedSubvaults = {};
|
||||
$scope.selectedCollections = {};
|
||||
};
|
||||
|
||||
$scope.submitPromise = null;
|
||||
@ -107,13 +107,13 @@
|
||||
$scope.login.organizationId = model.organizationId;
|
||||
|
||||
var request = {
|
||||
subvaultIds: [],
|
||||
collectionIds: [],
|
||||
cipher: cipherService.encryptLogin($scope.login)
|
||||
};
|
||||
|
||||
for (var id in $scope.selectedSubvaults) {
|
||||
if ($scope.selectedSubvaults.hasOwnProperty(id)) {
|
||||
request.subvaultIds.push(id);
|
||||
for (var id in $scope.selectedCollections) {
|
||||
if ($scope.selectedCollections.hasOwnProperty(id)) {
|
||||
request.collectionIds.push(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,24 +1,24 @@
|
||||
angular
|
||||
.module('bit.vault')
|
||||
|
||||
.controller('vaultSubvaultsController', function ($scope, apiService, cipherService, $analytics, $q, $localStorage,
|
||||
.controller('vaultCollectionsController', function ($scope, apiService, cipherService, $analytics, $q, $localStorage,
|
||||
$uibModal, $filter, $rootScope) {
|
||||
$scope.logins = [];
|
||||
$scope.subvaults = [];
|
||||
$scope.collections = [];
|
||||
$scope.loading = true;
|
||||
|
||||
$scope.$on('$viewContentLoaded', function () {
|
||||
var subvaultPromise = apiService.subvaults.listMe({}, function (subvaults) {
|
||||
var decSubvaults = [];
|
||||
var collectionPromise = apiService.collections.listMe({}, function (collections) {
|
||||
var decCollections = [];
|
||||
|
||||
for (var i = 0; i < subvaults.Data.length; i++) {
|
||||
var decSubvault = cipherService.decryptSubvault(subvaults.Data[i], null, true);
|
||||
decSubvault.collapsed = $localStorage.collapsedSubvaults &&
|
||||
decSubvault.id in $localStorage.collapsedSubvaults;
|
||||
decSubvaults.push(decSubvault);
|
||||
for (var i = 0; i < collections.Data.length; i++) {
|
||||
var decCollection = cipherService.decryptCollection(collections.Data[i], null, true);
|
||||
decCollection.collapsed = $localStorage.collapsedCollections &&
|
||||
decCollection.id in $localStorage.collapsedCollections;
|
||||
decCollections.push(decCollection);
|
||||
}
|
||||
|
||||
$scope.subvaults = decSubvaults;
|
||||
$scope.collections = decCollections;
|
||||
}).$promise;
|
||||
|
||||
var cipherPromise = apiService.ciphers.listDetails({}, function (ciphers) {
|
||||
@ -34,27 +34,27 @@
|
||||
$scope.logins = decLogins;
|
||||
}).$promise;
|
||||
|
||||
$q.all([subvaultPromise, cipherPromise]).then(function () {
|
||||
$q.all([collectionPromise, cipherPromise]).then(function () {
|
||||
$scope.loading = false;
|
||||
});
|
||||
});
|
||||
|
||||
$scope.filterBySubvault = function (subvault) {
|
||||
$scope.filterByCollection = function (collection) {
|
||||
return function (cipher) {
|
||||
return cipher.subvaultIds.indexOf(subvault.id) > -1;
|
||||
return cipher.collectionIds.indexOf(collection.id) > -1;
|
||||
};
|
||||
};
|
||||
|
||||
$scope.collapseExpand = function (subvault) {
|
||||
if (!$localStorage.collapsedSubvaults) {
|
||||
$localStorage.collapsedSubvaults = {};
|
||||
$scope.collapseExpand = function (collection) {
|
||||
if (!$localStorage.collapsedCollections) {
|
||||
$localStorage.collapsedCollections = {};
|
||||
}
|
||||
|
||||
if (subvault.id in $localStorage.collapsedSubvaults) {
|
||||
delete $localStorage.collapsedSubvaults[subvault.id];
|
||||
if (collection.id in $localStorage.collapsedCollections) {
|
||||
delete $localStorage.collapsedCollections[collection.id];
|
||||
}
|
||||
else {
|
||||
$localStorage.collapsedSubvaults[subvault.id] = true;
|
||||
$localStorage.collapsedCollections[collection.id] = true;
|
||||
}
|
||||
};
|
||||
|
||||
@ -92,47 +92,47 @@
|
||||
});
|
||||
};
|
||||
|
||||
$scope.editSubvaults = function (login) {
|
||||
$scope.editCollections = function (login) {
|
||||
var modal = $uibModal.open({
|
||||
animation: true,
|
||||
templateUrl: 'app/vault/views/vaultLoginSubvaults.html',
|
||||
controller: 'vaultLoginSubvaultsController',
|
||||
templateUrl: 'app/vault/views/vaultLoginCollections.html',
|
||||
controller: 'vaultLoginCollectionsController',
|
||||
resolve: {
|
||||
loginId: function () { return login.id; }
|
||||
}
|
||||
});
|
||||
|
||||
modal.result.then(function (response) {
|
||||
if (response.subvaultIds) {
|
||||
login.subvaultIds = response.subvaultIds;
|
||||
if (response.collectionIds) {
|
||||
login.collectionIds = response.collectionIds;
|
||||
|
||||
if (!response.subvaultIds.length) {
|
||||
if (!response.collectionIds.length) {
|
||||
removeRootLogin(findRootLogin(login));
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$scope.removeLogin = function (login, subvault) {
|
||||
$scope.removeLogin = function (login, collection) {
|
||||
if (!confirm('Are you sure you want to remove this login (' + login.name + ') from the ' +
|
||||
'subvault (' + subvault.name + ') ?')) {
|
||||
'collection (' + collection.name + ') ?')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var request = {
|
||||
subvaultIds: []
|
||||
collectionIds: []
|
||||
};
|
||||
|
||||
for (var i = 0; i < login.subvaultIds.length; i++) {
|
||||
if (login.subvaultIds[i] !== subvault.id) {
|
||||
request.subvaultIds.push(login.subvaultIds[i]);
|
||||
for (var i = 0; i < login.collectionIds.length; i++) {
|
||||
if (login.collectionIds[i] !== collection.id) {
|
||||
request.collectionIds.push(login.collectionIds[i]);
|
||||
}
|
||||
}
|
||||
|
||||
apiService.ciphers.putSubvaults({ id: login.id }, request).$promise.then(function (response) {
|
||||
$analytics.eventTrack('Removed From Subvault');
|
||||
login.subvaultIds = request.subvaultIds;
|
||||
if (!login.subvaultIds.length) {
|
||||
apiService.ciphers.putCollections({ id: login.id }, request).$promise.then(function (response) {
|
||||
$analytics.eventTrack('Removed From Collection');
|
||||
login.collectionIds = request.collectionIds;
|
||||
if (!login.collectionIds.length) {
|
||||
removeRootLogin(findRootLogin(login));
|
||||
}
|
||||
});
|
||||
|
@ -67,8 +67,8 @@
|
||||
</a>
|
||||
</li>
|
||||
<li ng-show="login.organizationId">
|
||||
<a href="javascript:void(0)" ng-click="subvaults(login)">
|
||||
<i class="fa fa-fw fa-share-alt"></i> Subvaults
|
||||
<a href="javascript:void(0)" ng-click="collections(login)">
|
||||
<i class="fa fa-fw fa-share-alt"></i> Collections
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
@ -154,8 +154,8 @@
|
||||
</a>
|
||||
</li>
|
||||
<li ng-show="login.organizationId">
|
||||
<a href="javascript:void(0)" ng-click="subvaults(login)">
|
||||
<i class="fa fa-fw fa-share-alt"></i> Subvaults
|
||||
<a href="javascript:void(0)" ng-click="collections(login)">
|
||||
<i class="fa fa-fw fa-share-alt"></i> Collections
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
|
@ -1,45 +1,45 @@
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" ng-click="close()" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title"><i class="fa fa-share-alt"></i> Subvaults <small>{{login.name}}</small></h4>
|
||||
<h4 class="modal-title"><i class="fa fa-share-alt"></i> Collections <small>{{login.name}}</small></h4>
|
||||
</div>
|
||||
<form name="form" ng-submit="form.$valid && submit()" api-form="submitPromise">
|
||||
<div class="modal-body">
|
||||
<p>Edit the subvaults that this login is being shared with.</p>
|
||||
<p>Edit the collections that this login is being shared with.</p>
|
||||
<div class="callout callout-danger validation-errors" ng-show="form.$errors">
|
||||
<h4>Errors have occured</h4>
|
||||
<ul>
|
||||
<li ng-repeat="e in form.$errors">{{e}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div ng-show="loadingSubvaults && !subvaults.length">
|
||||
<div ng-show="loadingCollections && !collections.length">
|
||||
Loading...
|
||||
</div>
|
||||
<div ng-show="!loadingSubvaults && !subvaults.length" class="callout callout-default">
|
||||
<p>No subvaults to manage.</p>
|
||||
<div ng-show="!loadingCollections && !collections.length" class="callout callout-default">
|
||||
<p>No collections to manage.</p>
|
||||
</div>
|
||||
<div class="table-responsive" ng-show="subvaults.length" style="margin: 0;">
|
||||
<div class="table-responsive" ng-show="collections.length" style="margin: 0;">
|
||||
<table class="table table-striped table-hover" style="margin: 0;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 40px;">
|
||||
<input type="checkbox"
|
||||
ng-checked="allSelected()"
|
||||
ng-click="toggleSubvaultSelectionAll($event)">
|
||||
ng-click="toggleCollectionSelectionAll($event)">
|
||||
</th>
|
||||
<th>Name</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="subvault in subvaults | orderBy: ['name']">
|
||||
<tr ng-repeat="collection in collections | orderBy: ['name']">
|
||||
<td valign="middle">
|
||||
<input type="checkbox"
|
||||
name="selectedSubvaults[]"
|
||||
value="{{subvault.id}}"
|
||||
ng-checked="subvaultSelected(subvault)"
|
||||
ng-click="toggleSubvaultSelection(subvault.id)">
|
||||
name="selectedCollections[]"
|
||||
value="{{collection.id}}"
|
||||
ng-checked="collectionSelected(collection)"
|
||||
ng-click="toggleCollectionSelection(collection.id)">
|
||||
</td>
|
||||
<td valign="middle" ng-click="toggleSubvaultSelection(subvault.id)">
|
||||
{{subvault.name}}
|
||||
<td valign="middle" ng-click="toggleCollectionSelection(collection.id)">
|
||||
{{collection.name}}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@ -47,7 +47,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" class="btn btn-primary btn-flat" ng-disabled="form.$loading" ng-show="subvaults.length">
|
||||
<button type="submit" class="btn btn-primary btn-flat" ng-disabled="form.$loading" ng-show="collections.length">
|
||||
<i class="fa fa-refresh fa-spin loading-icon" ng-show="form.$loading"></i>Save
|
||||
</button>
|
||||
<button type="button" class="btn btn-default btn-flat" ng-click="close()">Close</button>
|
||||
|
@ -26,38 +26,38 @@
|
||||
<option ng-repeat="org in organizations | orderBy: ['name']" value="{{org.id}}">{{org.name}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<h4 ng-hide="!loadingSubvaults && !orgSubvaults.length">Subvault Access</h4>
|
||||
<div ng-show="loadingSubvaults && !orgSubvaults.length">
|
||||
<h4 ng-hide="!loadingCollections && !orgCollections.length">Collection Access</h4>
|
||||
<div ng-show="loadingCollections && !orgCollections.length">
|
||||
<p>Loading...</p>
|
||||
</div>
|
||||
<div ng-show="!loadingSubvaults && !orgSubvaults.length" class="callout callout-default">
|
||||
<h4><i class="fa fa-info-circle"></i> No Subvaults</h4>
|
||||
<p>You do not have write access to any subvaults for this organization.</p>
|
||||
<div ng-show="!loadingCollections && !orgCollections.length" class="callout callout-default">
|
||||
<h4><i class="fa fa-info-circle"></i> No Collections</h4>
|
||||
<p>You do not have write access to any collections for this organization.</p>
|
||||
</div>
|
||||
<div class="table-responsive" ng-show="orgSubvaults.length" style="margin: 0;">
|
||||
<div class="table-responsive" ng-show="orgCollections.length" style="margin: 0;">
|
||||
<table class="table table-striped table-hover" style="margin: 0;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 40px;">
|
||||
<input type="checkbox"
|
||||
ng-checked="allSelected()"
|
||||
ng-click="toggleSubvaultSelectionAll($event)">
|
||||
ng-click="toggleCollectionSelectionAll($event)">
|
||||
</th>
|
||||
<th>Name</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="subvault in orgSubvaults =
|
||||
(subvaults | filter: { organizationId: model.organizationId } | orderBy: ['name'])">
|
||||
<tr ng-repeat="collection in orgCollections =
|
||||
(collections | filter: { organizationId: model.organizationId } | orderBy: ['name'])">
|
||||
<td valign="middle">
|
||||
<input type="checkbox"
|
||||
name="selectedSubvaults[]"
|
||||
value="{{subvault.id}}"
|
||||
ng-checked="subvaultSelected(subvault)"
|
||||
ng-click="toggleSubvaultSelection(subvault.id)">
|
||||
name="selectedCollections[]"
|
||||
value="{{collection.id}}"
|
||||
ng-checked="collectionSelected(collection)"
|
||||
ng-click="toggleCollectionSelection(collection.id)">
|
||||
</td>
|
||||
<td valign="middle" ng-click="toggleSubvaultSelection(subvault.id)">
|
||||
{{subvault.name}}
|
||||
<td valign="middle" ng-click="toggleCollectionSelection(collection.id)">
|
||||
{{collection.name}}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@ -1,57 +1,57 @@
|
||||
<section class="content-header">
|
||||
<h1>
|
||||
Subvaults
|
||||
Collections
|
||||
<small>
|
||||
<span ng-pluralize count="subvaults.length" when="{'1': '{} subvault', 'other': '{} subvaults'}"></span>,
|
||||
<span ng-pluralize count="collections.length" when="{'1': '{} collection', 'other': '{} collections'}"></span>,
|
||||
<span ng-pluralize count="logins.length" when="{'1': '{} login', 'other': '{} logins'}"></span>
|
||||
</small>
|
||||
</h1>
|
||||
</section>
|
||||
<section class="content">
|
||||
<div ng-show="loading && !subvaults.length">
|
||||
<div ng-show="loading && !collections.length">
|
||||
<p>Loading...</p>
|
||||
</div>
|
||||
<div class="callout callout-default" style="background: #fff;" ng-show="!loading && !subvaults.length">
|
||||
<h4><i class="fa fa-info-circle"></i> No Subvaults</h4>
|
||||
<div class="callout callout-default" style="background: #fff;" ng-show="!loading && !collections.length">
|
||||
<h4><i class="fa fa-info-circle"></i> No Collections</h4>
|
||||
<p>
|
||||
You do not have any subvaults being shared with you.
|
||||
You do not have any collections being shared with you.
|
||||
</p>
|
||||
<p>
|
||||
Subvaults allow you to share logins with other bitwarden users. To start using subvaults create an organization or
|
||||
Collections allow you to share logins with other bitwarden users. To start using collections create an organization or
|
||||
ask an existing organization to invite you.
|
||||
</p>
|
||||
<a ui-sref="backend.user.settingsCreateOrg" class="btn btn-default btn-flat">
|
||||
Create an Organization
|
||||
</a>
|
||||
</div>
|
||||
<div class="box" ng-class="{'collapsed-box': subvault.collapsed}" ng-repeat="subvault in subvaults |
|
||||
orderBy: ['name'] track by subvault.id"
|
||||
ng-show="subvaults.length">
|
||||
<div class="box" ng-class="{'collapsed-box': collection.collapsed}" ng-repeat="collection in collections |
|
||||
orderBy: ['name'] track by collection.id"
|
||||
ng-show="collections.length">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">
|
||||
<i class="fa fa-share-alt-square"></i>
|
||||
{{subvault.name}}
|
||||
<small ng-pluralize count="subvaultLogins.length" when="{'1': '{} login', 'other': '{} logins'}"></small>
|
||||
{{collection.name}}
|
||||
<small ng-pluralize count="collectionLogins.length" when="{'1': '{} login', 'other': '{} logins'}"></small>
|
||||
</h3>
|
||||
<div class="box-tools">
|
||||
<button type="button" class="btn btn-box-tool" data-widget="collapse" title="Collapse/Expand"
|
||||
ng-click="collapseExpand(subvault)">
|
||||
<i class="fa" ng-class="{'fa-minus': !subvault.collapsed, 'fa-plus': subvault.collapsed}"></i>
|
||||
ng-click="collapseExpand(collection)">
|
||||
<i class="fa" ng-class="{'fa-minus': !collection.collapsed, 'fa-plus': collection.collapsed}"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body" ng-class="{'no-padding': subvaultLogins.length}">
|
||||
<div ng-show="!subvaultLogins.length">
|
||||
<p>No logins in this subvault.</p>
|
||||
<div class="box-body" ng-class="{'no-padding': collectionLogins.length}">
|
||||
<div ng-show="!collectionLogins.length">
|
||||
<p>No logins in this collection.</p>
|
||||
<p>
|
||||
Share a login to this subvault by selecting <i class="fa fa-share-alt"></i> <b>Share</b> or
|
||||
<i class="fa fa-share-alt"></i> <b>Subvaults</b> from the login's options (<i class="fa fa-cog"></i>) menu.
|
||||
Share a login to this collection by selecting <i class="fa fa-share-alt"></i> <b>Share</b> or
|
||||
<i class="fa fa-share-alt"></i> <b>Collections</b> from the login's options (<i class="fa fa-cog"></i>) menu.
|
||||
</p>
|
||||
</div>
|
||||
<div class="table-responsive" ng-show="subvaultLogins.length">
|
||||
<div class="table-responsive" ng-show="collectionLogins.length">
|
||||
<table class="table table-striped table-hover table-vmiddle">
|
||||
<tbody>
|
||||
<tr ng-repeat="login in subvaultLogins = (logins | filter: filterBySubvault(subvault) |
|
||||
<tr ng-repeat="login in collectionLogins = (logins | filter: filterByCollection(collection) |
|
||||
orderBy: ['name', 'username']) track by login.id">
|
||||
<td style="width: 70px;">
|
||||
<div class="btn-group" data-append-to="body">
|
||||
@ -65,12 +65,12 @@
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="javascript:void(0)" ng-click="editSubvaults(login)">
|
||||
<i class="fa fa-fw fa-share-alt"></i> Subvaults
|
||||
<a href="javascript:void(0)" ng-click="editCollections(login)">
|
||||
<i class="fa fa-fw fa-share-alt"></i> Collections
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="javascript:void(0)" ng-click="removeLogin(login, subvault)" class="text-red">
|
||||
<a href="javascript:void(0)" ng-click="removeLogin(login, collection)" class="text-red">
|
||||
<i class="fa fa-fw fa-remove"></i> Remove
|
||||
</a>
|
||||
</li>
|
||||
|
@ -41,9 +41,9 @@
|
||||
<i class="fa fa-lock fa-fw"></i> <span>Vault</span>
|
||||
</a>
|
||||
</li>
|
||||
<li ng-class="{active: $state.is('backend.org.subvaults')}">
|
||||
<a ui-sref="backend.org.subvaults({orgId: params.orgId})">
|
||||
<i class="fa fa-share-alt fa-fw"></i> <span>Subvaults</span>
|
||||
<li ng-class="{active: $state.is('backend.org.collections')}">
|
||||
<a ui-sref="backend.org.collections({orgId: params.orgId})">
|
||||
<i class="fa fa-share-alt fa-fw"></i> <span>Collections</span>
|
||||
</a>
|
||||
</li>
|
||||
<li ng-class="{active: $state.is('backend.org.people')}">
|
||||
|
@ -54,11 +54,11 @@
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="treeview" ng-class="{active: $state.is('backend.user.subvaults')}">
|
||||
<a ui-sref="backend.user.subvaults">
|
||||
<li class="treeview" ng-class="{active: $state.is('backend.user.collections')}">
|
||||
<a ui-sref="backend.user.collections">
|
||||
|
||||
<small class="label pull-right bg-orange">NEW</small>
|
||||
<i class="fa fa-share-alt fa-fw"></i> <span>Subvaults</span>
|
||||
<i class="fa fa-share-alt fa-fw"></i> <span>Collections</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="treeview" ng-class="{active: $state.is('backend.user.tools')}">
|
||||
|
@ -126,18 +126,18 @@
|
||||
<script src="app/vault/vaultEditFolderController.js"></script>
|
||||
<script src="app/vault/vaultAddFolderController.js"></script>
|
||||
<script src="app/vault/vaultShareController.js"></script>
|
||||
<script src="app/vault/vaultSubvaultsController.js"></script>
|
||||
<script src="app/vault/vaultLoginSubvaultsController.js"></script>
|
||||
<script src="app/vault/vaultCollectionsController.js"></script>
|
||||
<script src="app/vault/vaultLoginCollectionsController.js"></script>
|
||||
|
||||
<script src="app/organization/organizationModule.js"></script>
|
||||
<script src="app/organization/organizationDashboardController.js"></script>
|
||||
<script src="app/organization/organizationPeopleController.js"></script>
|
||||
<script src="app/organization/organizationPeopleInviteController.js"></script>
|
||||
<script src="app/organization/organizationPeopleEditController.js"></script>
|
||||
<script src="app/organization/organizationSubvaultsController.js"></script>
|
||||
<script src="app/organization/organizationSubvaultsAddController.js"></script>
|
||||
<script src="app/organization/organizationSubvaultsEditController.js"></script>
|
||||
<script src="app/organization/organizationSubvaultsUsersController.js"></script>
|
||||
<script src="app/organization/organizationCollectionsController.js"></script>
|
||||
<script src="app/organization/organizationCollectionsAddController.js"></script>
|
||||
<script src="app/organization/organizationCollectionsEditController.js"></script>
|
||||
<script src="app/organization/organizationCollectionsUsersController.js"></script>
|
||||
<script src="app/organization/organizationSettingsController.js"></script>
|
||||
<script src="app/organization/organizationBillingController.js"></script>
|
||||
<script src="app/organization/organizationBillingChangePaymentController.js"></script>
|
||||
@ -145,9 +145,9 @@
|
||||
<script src="app/organization/organizationDeleteController.js"></script>
|
||||
<script src="app/organization/organizationBillingChangePlanController.js"></script>
|
||||
<script src="app/organization/organizationVaultController.js"></script>
|
||||
<script src="app/organization/organizationVaultLoginSubvaultsController.js"></script>
|
||||
<script src="app/organization/organizationVaultLoginCollectionsController.js"></script>
|
||||
<script src="app/organization/organizationGroupsController.js"></script>
|
||||
<script src="app/organization/organizationSubvaultsGroupsController.js"></script>
|
||||
<script src="app/organization/organizationCollectionsGroupsController.js"></script>
|
||||
|
||||
<script src="app/settings/settingsModule.js"></script>
|
||||
<script src="app/settings/settingsController.js"></script>
|
||||
|
Loading…
Reference in New Issue
Block a user