Move and list ciphers from org subvaults

This commit is contained in:
Kyle Spearrin 2017-03-21 00:05:20 -04:00
parent 22ab5d334e
commit b85a45d8f9
7 changed files with 131 additions and 9 deletions

View File

@ -26,6 +26,7 @@
list: { method: 'GET', params: {} },
'import': { url: _apiUri + '/ciphers/import', method: 'POST', params: {} },
favorite: { url: _apiUri + '/ciphers/:id/favorite', method: 'POST', params: { id: '@id' } },
move: { url: _apiUri + '/ciphers/:id/move', method: 'POST', params: { id: '@id' } },
del: { url: _apiUri + '/ciphers/:id/delete', method: 'POST', params: { id: '@id' } }
});

View File

@ -19,12 +19,13 @@ angular
if (!encryptedLogin) throw "encryptedLogin is undefined or null";
var key = null;
if (encryptedLogin.Key) {
key = cryptoService.rsaDecrypt(encryptedLogin.Key);
if (encryptedLogin.OrganizationId) {
key = cryptoService.getOrgKey(encryptedLogin.OrganizationId);
}
var login = {
id: encryptedLogin.Id,
organizationId: encryptedLogin.OrganizationId,
'type': 1,
folderId: encryptedLogin.FolderId,
favorite: encryptedLogin.Favorite,
@ -32,8 +33,7 @@ angular
uri: encryptedLogin.Uri && encryptedLogin.Uri !== '' ? cryptoService.decrypt(encryptedLogin.Uri, key) : null,
username: encryptedLogin.Username && encryptedLogin.Username !== '' ? cryptoService.decrypt(encryptedLogin.Username, key) : null,
password: encryptedLogin.Password && encryptedLogin.Password !== '' ? cryptoService.decrypt(encryptedLogin.Password, key) : null,
notes: encryptedLogin.Notes && encryptedLogin.Notes !== '' ? cryptoService.decrypt(encryptedLogin.Notes, key) : null,
key: encryptedLogin.Key
notes: encryptedLogin.Notes && encryptedLogin.Notes !== '' ? cryptoService.decrypt(encryptedLogin.Notes, key) : null
};
if (encryptedLogin.Folder) {
@ -49,12 +49,13 @@ angular
if (!encryptedCipher) throw "encryptedCipher is undefined or null";
var key = null;
if (encryptedCipher.Key) {
key = cryptoService.rsaDecrypt(encryptedCipher.Key);
if (encryptedCipher.OrganizationId) {
key = cryptoService.getOrgKey(encryptedCipher.OrganizationId);
}
var login = {
id: encryptedCipher.Id,
organizationId: encryptedCipher.OrganizationId,
folderId: encryptedCipher.FolderId,
favorite: encryptedCipher.Favorite,
name: _service.decryptProperty(encryptedCipher.Data.Name, key, false),
@ -119,7 +120,7 @@ angular
};
};
_service.decryptProperty = function(property, key, checkEmpty) {
_service.decryptProperty = function (property, key, checkEmpty) {
if (checkEmpty && (!property || property === '')) {
return null;
}
@ -148,9 +149,14 @@ angular
_service.encryptLogin = function (unencryptedLogin, key) {
if (!unencryptedLogin) throw "unencryptedLogin is undefined or null";
if (unencryptedLogin.organizationId) {
key = key || cryptoService.getOrgKey(unencryptedLogin.organizationId);
}
return {
id: unencryptedLogin.id,
'type': 1,
organizationId: unencryptedLogin.organizationId || null,
folderId: unencryptedLogin.folderId === '' ? null : unencryptedLogin.folderId,
favorite: unencryptedLogin.favorite !== null ? unencryptedLogin.favorite : false,
uri: !unencryptedLogin.uri || unencryptedLogin.uri === '' ? null : cryptoService.encrypt(unencryptedLogin.uri, key),

View File

@ -11,7 +11,7 @@
var folderPromise = apiService.folders.list({}, function (folders) {
var decFolders = [{
id: null,
name: '(none)'
name: 'No Folder'
}];
for (var i = 0; i < folders.Data.length; i++) {
@ -172,4 +172,20 @@
var logins = $filter('filter')($scope.logins, { folderId: folder.id });
return logins.length === 0;
};
$scope.share = function (login) {
var modal = $uibModal.open({
animation: true,
templateUrl: 'app/vault/views/vaultShare.html',
controller: 'vaultShareController',
size: 'sm',
resolve: {
loginId: function () { return login.id; }
}
});
modal.result.then(function () {
});
};
});

View File

@ -0,0 +1,61 @@
angular
.module('bit.vault')
.controller('vaultShareController', function ($scope, apiService, $uibModalInstance, authService, cipherService, loginId, $analytics) {
$analytics.eventTrack('vaultShareController', { category: 'Modal' });
$scope.model = {};
$scope.login = {};
$scope.subvaults = [];
$scope.organizations = [];
apiService.logins.get({ id: loginId }, function (login) {
$scope.login = cipherService.decryptLogin(login);
});
var profile = authService.getUserProfile();
if (profile && profile.organizations) {
var orgs = [];
for (var i = 0; i < profile.organizations.length; i++) {
orgs.push({
id: profile.organizations[i].id,
name: profile.organizations[i].name
});
if (i === 0) {
$scope.model.organizationId = profile.organizations[i].id;
}
}
$scope.organizations = orgs;
apiService.subvaults.listMe(function (response) {
var subvaults = [];
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);
}
$scope.subvaults = subvaults;
});
}
$scope.submitPromise = null;
$scope.submit = function (model) {
$scope.login.organizationId = model.organizationId;
var request = {
subvaultIds: model.subvaultIds,
cipher: cipherService.encryptLogin($scope.login)
};
$scope.savePromise = apiService.ciphers.move({ id: loginId }, request, function (response) {
$analytics.eventTrack('Shared Login');
$uibModalInstance.close();
}).$promise;
};
$scope.close = function () {
$uibModalInstance.dismiss('cancel');
};
});

View File

@ -47,7 +47,7 @@
<table class="table table-striped table-hover table-selectable">
<thead>
<tr>
<th style="width: 75px; min-width: 75px;"></th>
<th style="width: 110px; min-width: 110px;"></th>
<th>Name</th>
<th style="width: 300px;">Username</th>
</tr>
@ -64,6 +64,10 @@
uib-tooltip="View/Edit">
<i class="fa fa-lg fa-pencil"></i>
</button>
<button type="button" ng-click="share(login)" class="btn btn-link btn-table"
uib-tooltip="Share">
<i class="fa fa-lg fa-share-alt"></i>
</button>
</td>
<td ng-click="editLogin(login)">
<span ng-click="$event.stopPropagation()">

View File

@ -0,0 +1,33 @@
<div class="modal-header">
<button type="button" class="close" ng-click="close()" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title"><i class="fa fa-share-alt"></i> Share Login <small>{{login.name}}</small></h4>
</div>
<form name="form" ng-submit="form.$valid && submit(model)" api-form="submitPromise">
<div class="modal-body">
<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 class="form-group">
<label for="organization">Organization</label> <span>*</span>
<select id="organization" name="Organization" ng-model="model.organizationId" class="form-control">
<option ng-repeat="org in organizations | orderBy: ['name']" value="{{org.id}}">{{org.name}}</option>
</select>
</div>
<div class="form-group" show-errors>
<label for="subvaults">Subvault</label> <span>*</span>
<select id="subvaults" name="SubvaultIds" ng-model="model.subvaultIds" class="form-control" multiple api-field>
<option ng-repeat="subvault in subvaults | filter: { organizationId: model.organizationId } |
orderBy: ['name']" value="{{subvault.id}}">{{subvault.name}}</option>
</select>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary btn-flat" ng-disabled="form.$loading">
<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>
</div>
</form>

View File

@ -115,6 +115,7 @@
<script src="app/vault/vaultAddLoginController.js"></script>
<script src="app/vault/vaultEditFolderController.js"></script>
<script src="app/vault/vaultAddFolderController.js"></script>
<script src="app/vault/vaultShareController.js"></script>
<script src="app/sharing/sharingModule.js"></script>
<script src="app/sharing/sharingController.js"></script>