diff --git a/src/app/config.js b/src/app/config.js
index 0c4abe83..7b70adba 100644
--- a/src/app/config.js
+++ b/src/app/config.js
@@ -150,6 +150,12 @@ angular
controller: 'organizationBillingController',
data: { pageTitle: 'Organization Billing' }
})
+ .state('backend.org.vault', {
+ url: '/organization/:orgId/vault',
+ templateUrl: 'app/organization/views/organizationVault.html',
+ controller: 'organizationVaultController',
+ data: { pageTitle: 'Organization Vault' }
+ })
// Frontend
.state('frontend', {
diff --git a/src/app/organization/organizationVaultController.js b/src/app/organization/organizationVaultController.js
new file mode 100644
index 00000000..84ce96a1
--- /dev/null
+++ b/src/app/organization/organizationVaultController.js
@@ -0,0 +1,85 @@
+angular
+ .module('bit.vault')
+
+ .controller('organizationVaultController', function ($scope, apiService, cipherService, $analytics, $q, $state,
+ $localStorage, $uibModal, $filter) {
+ $scope.logins = [];
+ $scope.subvaults = [];
+ $scope.folders = [];
+ $scope.loading = true;
+
+ $scope.$on('$viewContentLoaded', function () {
+ var subvaultPromise = apiService.subvaults.listOrganization({ orgId: $state.params.orgId }, function (subvaults) {
+ var decSubvaults = [];
+
+ 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);
+ }
+
+ $scope.subvaults = decSubvaults;
+ }).$promise;
+
+ var cipherPromise = apiService.ciphers.listOrganizationDetails({ organizationId: $state.params.orgId },
+ function (ciphers) {
+ var decLogins = [];
+
+ for (var i = 0; i < ciphers.Data.length; i++) {
+ if (ciphers.Data[i].Type === 1) {
+ var decLogin = cipherService.decryptLoginPreview(ciphers.Data[i]);
+ decLogins.push(decLogin);
+ }
+ }
+
+ $scope.logins = decLogins;
+ }).$promise;
+
+ $q.all([subvaultPromise, cipherPromise]).then(function () {
+ $scope.loading = false;
+ });
+ });
+
+ $scope.filterBySubvault = function (subvault) {
+ return function (cipher) {
+ return cipher.subvaultIds.indexOf(subvault.id) > -1;
+ };
+ };
+
+ $scope.filterByOrphaned = function () {
+ return function (cipher) {
+ return !cipher.subvaultIds || !cipher.subvaultIds.length;
+ };
+ };
+
+ $scope.collapseExpand = function (subvault) {
+ if (!$localStorage.collapsedOrgSubvaults) {
+ $localStorage.collapsedOrgSubvaults = {};
+ }
+
+ if (subvault.id in $localStorage.collapsedOrgSubvaults) {
+ delete $localStorage.collapsedOrgSubvaults[subvault.id];
+ }
+ else {
+ $localStorage.collapsedOrgSubvaults[subvault.id] = true;
+ }
+ };
+
+ $scope.editSubvaults = function (login) {
+ var modal = $uibModal.open({
+ animation: true,
+ templateUrl: 'app/vault/views/vaultLoginSubvaults.html',
+ controller: 'vaultOrganizationLoginSubvaultsController',
+ resolve: {
+ loginId: function () { return login.id; }
+ }
+ });
+
+ modal.result.then(function (response) {
+ if (response.subvaultIds) {
+ login.subvaultIds = response.subvaultIds;
+ }
+ });
+ };
+ });
diff --git a/src/app/organization/views/organizationVault.html b/src/app/organization/views/organizationVault.html
new file mode 100644
index 00000000..360aa9e6
--- /dev/null
+++ b/src/app/organization/views/organizationVault.html
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+
+
No logins in this subvault.
+
+
+
+
+
+
diff --git a/src/app/services/apiService.js b/src/app/services/apiService.js
index 225a62f2..0238ede7 100644
--- a/src/app/services/apiService.js
+++ b/src/app/services/apiService.js
@@ -26,6 +26,7 @@
getFullDetails: { url: _apiUri + '/ciphers/:id/full-details', method: 'GET', params: { id: '@id' } },
list: { method: 'GET', params: {} },
listDetails: { url: _apiUri + '/ciphers/details', method: 'GET', params: {} },
+ listOrganizationDetails: { url: _apiUri + '/ciphers/organization-details', method: 'GET', params: {} },
'import': { url: _apiUri + '/ciphers/import', method: 'POST', params: {} },
favorite: { url: _apiUri + '/ciphers/:id/favorite', method: 'POST', params: { id: '@id' } },
putPartial: { url: _apiUri + '/ciphers/:id/partial', method: 'POST', params: { id: '@id' } },
diff --git a/src/app/views/organizationLayout.html b/src/app/views/organizationLayout.html
index 7050b718..c46146be 100644
--- a/src/app/views/organizationLayout.html
+++ b/src/app/views/organizationLayout.html
@@ -46,6 +46,11 @@
Subvaults
+
+
+ Vault
+
+
Billing
diff --git a/src/index.html b/src/index.html
index 11db7dea..52d9e491 100644
--- a/src/index.html
+++ b/src/index.html
@@ -144,6 +144,7 @@
+