mirror of
https://github.com/nextcloud/passman.git
synced 2024-09-20 14:56:21 +08:00
Remove server side encryption setting at admin page.
Fix counting credentials (Fixes #235) Fix for deleting shared credental (Fixes #232) Fix for empty sharing keys in vaults (Fixes #230) Fix removed shared credential leaves tags Fix for lastpass import #233 Disable share button when link sharing is disabled. Or when it's not shared with a user. Add issue template Bump version
This commit is contained in:
parent
053a364d88
commit
0a386d77ce
44
ISSUE_TEMPLATE.md
Normal file
44
ISSUE_TEMPLATE.md
Normal file
|
@ -0,0 +1,44 @@
|
|||
<!--
|
||||
Thanks for reporting issues back to us!
|
||||
This is the bug tracker for the Passman. Find passman-webextension at https://github.com/nextcloud/passman-webextension
|
||||
|
||||
|
||||
To make it possible for us to help you please fill out below information carefully.
|
||||
-->
|
||||
### Steps to reproduce
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
|
||||
### Expected behaviour
|
||||
Tell us what should happen
|
||||
|
||||
### Actual behaviour
|
||||
Tell us what happens instead
|
||||
|
||||
### Configuration
|
||||
**Operating system**:
|
||||
|
||||
|
||||
**Browser**:
|
||||
|
||||
|
||||
**Extensions that might cause interference**:
|
||||
|
||||
|
||||
**Passman version**:
|
||||
|
||||
|
||||
**Nextcloud version**:
|
||||
|
||||
#### Browser log
|
||||
<details>
|
||||
<summary>Browser log</summary>
|
||||
```
|
||||
Insert your browser log here, this could for example include:
|
||||
|
||||
a) The javascript console log
|
||||
b) The network log
|
||||
c) ...
|
||||
```
|
||||
</details>
|
|
@ -18,7 +18,7 @@ For an demo of this app visit [https://demo.passman.cc](https://demo.passman.cc)
|
|||
]]></description>
|
||||
|
||||
<licence>AGPL</licence>
|
||||
<version>2.0.1</version>
|
||||
<version>2.0.2</version>
|
||||
<author homepage="https://github.com/brantje">Sander Brand</author>
|
||||
<author homepage="https://github.com/animalillo">Marcos Zuriaga</author>
|
||||
<namespace>Passman</namespace>
|
||||
|
|
|
@ -79,9 +79,6 @@
|
|||
//$location.path('/')
|
||||
|
||||
}
|
||||
if (_credential.tags) {
|
||||
TagService.addTags(_credential.tags);
|
||||
}
|
||||
_credentials[i] = _credential;
|
||||
}
|
||||
|
||||
|
@ -100,14 +97,23 @@
|
|||
_shared_credential_data.acl = _shared_credential;
|
||||
_shared_credential_data.acl.permissions = new SharingACL(_shared_credential_data.acl.permissions);
|
||||
_shared_credential_data.tags_raw = _shared_credential_data.tags;
|
||||
if (_shared_credential_data.tags) {
|
||||
TagService.addTags(_shared_credential_data.tags);
|
||||
}
|
||||
_credentials.push(_shared_credential_data);
|
||||
}
|
||||
}
|
||||
angular.merge($scope.active_vault.credentials, _credentials);
|
||||
$scope.show_spinner = false;
|
||||
|
||||
if(!vault.private_sharing_key){
|
||||
var key_size = 1024;
|
||||
ShareService.generateRSAKeys(key_size).then(function (kp) {
|
||||
var pem = ShareService.rsaKeyPairToPEM(kp);
|
||||
$scope.creating_keys = false;
|
||||
$scope.active_vault.private_sharing_key = pem.privateKey;
|
||||
$scope.active_vault.public_sharing_key = pem.publicKey;
|
||||
$scope.$digest();
|
||||
VaultService.updateSharingKeys($scope.active_vault);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
@ -125,6 +131,7 @@
|
|||
};
|
||||
|
||||
|
||||
|
||||
var refresh_data_interval = null;
|
||||
if ($scope.active_vault) {
|
||||
$scope.$parent.selectedVault = true;
|
||||
|
@ -257,7 +264,8 @@
|
|||
}
|
||||
notification = NotificationService.showNotification($translate.instant('credential.deleted'), 5000,
|
||||
function () {
|
||||
CredentialService.updateCredential(_credential).then(function (result) {
|
||||
var key = CredentialService.getSharedKeyFromCredential(_credential);
|
||||
CredentialService.updateCredential(_credential, false, key).then(function (result) {
|
||||
if (result.delete_time > 0) {
|
||||
notification = false;
|
||||
|
||||
|
@ -286,7 +294,8 @@
|
|||
}
|
||||
NotificationService.showNotification($translate.instant('credential.recovered'), 5000,
|
||||
function () {
|
||||
CredentialService.updateCredential(_credential).then(function () {
|
||||
var key = CredentialService.getSharedKeyFromCredential(_credential);
|
||||
CredentialService.updateCredential(_credential, false, key).then(function () {
|
||||
notification = false;
|
||||
|
||||
});
|
||||
|
@ -329,7 +338,15 @@
|
|||
filtered_credentials = $filter('tagFilter')(filtered_credentials, $scope.selectedtags);
|
||||
filtered_credentials = $filter('filter')(filtered_credentials, {hidden: 0});
|
||||
$scope.filtered_credentials = filtered_credentials;
|
||||
$scope.filterOptions.selectedtags = angular.copy($scope.selectedtags);
|
||||
for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
|
||||
var _credential = $scope.active_vault.credentials[i];
|
||||
if (_credential.tags) {
|
||||
TagService.addTags(_credential.tags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}, true);
|
||||
|
||||
$scope.selectedtags = [];
|
||||
|
@ -406,21 +423,13 @@
|
|||
|
||||
$scope.downloadFile = function (credential, file) {
|
||||
var callback = function (result) {
|
||||
var key = null;
|
||||
var key = EncryptService.getSharedKeyFromCredential(credential);
|
||||
|
||||
if (!result.hasOwnProperty('file_data')) {
|
||||
NotificationService.showNotification($translate.instant('error.loading.file.perm'), 5000);
|
||||
return;
|
||||
|
||||
}
|
||||
if (!credential.hasOwnProperty('acl') && credential.hasOwnProperty('shared_key')) {
|
||||
if (credential.shared_key) {
|
||||
key = EncryptService.decryptString(angular.copy(credential.shared_key));
|
||||
}
|
||||
}
|
||||
if (credential.hasOwnProperty('acl')) {
|
||||
key = EncryptService.decryptString(angular.copy(credential.acl.shared_key));
|
||||
}
|
||||
|
||||
var file_data = EncryptService.decryptString(result.file_data, key);
|
||||
download(file_data, escapeHTML(file.filename), file.mimetype);
|
||||
|
||||
|
|
|
@ -237,19 +237,23 @@
|
|||
};
|
||||
|
||||
$scope.unshareCredential = function (credential) {
|
||||
ShareService.unshareCredential(credential);
|
||||
|
||||
var _credential = angular.copy(credential);
|
||||
var old_key = EncryptService.decryptString(angular.copy(_credential.shared_key));
|
||||
var new_key = VaultService.getActiveVault().vaultKey;
|
||||
_credential.shared_key = null;
|
||||
_credential.unshare_action = true;
|
||||
_credential.skip_revision = true;
|
||||
|
||||
_credential = CredentialService.encryptCredential(_credential, old_key);
|
||||
CredentialService.updateCredential(_credential, true).then(function () {
|
||||
NotificationService.showNotification($translate.instant('credential.unshared'), 4000);
|
||||
CredentialService.reencryptCredential(_credential.guid, old_key, new_key).then(function () {
|
||||
getAcl();
|
||||
CredentialService.reencryptCredential(_credential.guid, old_key, new_key, true).then(function (data) {
|
||||
getAcl();
|
||||
var c = data.cryptogram;
|
||||
c.shared_key = null;
|
||||
c.unshare_action = true;
|
||||
c.skip_revision = true;
|
||||
ShareService.unshareCredential(c);
|
||||
CredentialService.updateCredential(c, true).then(function () {
|
||||
NotificationService.showNotification($translate.instant('credential.unshared'), 4000);
|
||||
$scope.sharing_complete = true;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
63
js/app/directives/credentialcounter.js
Normal file
63
js/app/directives/credentialcounter.js
Normal file
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
* Nextcloud - passman
|
||||
*
|
||||
* @copyright Copyright (c) 2016, Sander Brand (brantje@gmail.com)
|
||||
* @copyright Copyright (c) 2016, Marcos Zuriaga Miguel (wolfi@wolfi.es)
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name passmanApp.directive:passwordGen
|
||||
* @description
|
||||
* # passwordGen
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.directive('credentialCounter', [function () {
|
||||
return {
|
||||
template: '<div ng-show="counter" translate="number.filtered" translate-values="{number_filtered: counter, credential_number: total}"></div>',
|
||||
replace: false,
|
||||
restrict: 'A',
|
||||
scope: {
|
||||
credentials: '=credentialCounter',
|
||||
deleteTime: '=',
|
||||
vault: '=',
|
||||
filters: '='
|
||||
},
|
||||
|
||||
link: function (scope) {
|
||||
function countCredentials() {
|
||||
var countedCredentials = 0;
|
||||
var total = 0;
|
||||
angular.forEach(scope.credentials, function (credential) {
|
||||
total = (credential.hidden !== 1) ? total + 1 : total;
|
||||
if(credential.delete_time >= scope.deleteTime && credential.hidden === 0){
|
||||
countedCredentials = countedCredentials+1;
|
||||
}
|
||||
});
|
||||
scope.counter = countedCredentials;
|
||||
scope.total = total;
|
||||
}
|
||||
scope.$watch('[credentials, deleteTime, filters]', function () {
|
||||
countCredentials();
|
||||
}, true);
|
||||
}
|
||||
};
|
||||
}]);
|
||||
}());
|
|
@ -82,13 +82,13 @@
|
|||
getEncryptedFields: function () {
|
||||
return _encryptedFields;
|
||||
},
|
||||
updateCredential: function (credential, skipEncyption) {
|
||||
updateCredential: function (credential, skipEncryption, key) {
|
||||
var _credential = angular.copy(credential);
|
||||
if (!skipEncyption) {
|
||||
if (!skipEncryption) {
|
||||
for (var i = 0; i < _encryptedFields.length; i++) {
|
||||
var field = _encryptedFields[i];
|
||||
var fieldValue = angular.copy(credential[field]);
|
||||
_credential[field] = EncryptService.encryptString(JSON.stringify(fieldValue));
|
||||
_credential[field] = EncryptService.encryptString(JSON.stringify(fieldValue), key);
|
||||
}
|
||||
}
|
||||
_credential.expire_time = new Date(angular.copy(credential.expire_time)).getTime() / 1000;
|
||||
|
@ -150,6 +150,18 @@
|
|||
}
|
||||
return credential;
|
||||
},
|
||||
getSharedKeyFromCredential: function (credential) {
|
||||
var key = null;
|
||||
if (!credential.hasOwnProperty('acl') && credential.hasOwnProperty('shared_key')) {
|
||||
if (credential.shared_key) {
|
||||
key = EncryptService.decryptString(angular.copy(credential.shared_key));
|
||||
}
|
||||
}
|
||||
if (credential.hasOwnProperty('acl')) {
|
||||
key = EncryptService.decryptString(angular.copy(credential.acl.shared_key));
|
||||
}
|
||||
return key;
|
||||
},
|
||||
getRevisions: function (guid) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/credentials/' + guid + '/revision');
|
||||
return $http.get(queryUrl).then(function (response) {
|
||||
|
@ -182,7 +194,7 @@
|
|||
}
|
||||
});
|
||||
},
|
||||
reencryptCredential: function (credential_guid, old_password, new_password) {
|
||||
reencryptCredential: function (credential_guid, old_password, new_password, skipSharingKey) {
|
||||
|
||||
var service = this;
|
||||
|
||||
|
@ -198,8 +210,7 @@
|
|||
this.parent.plain_credential = service.decryptCredential(credential, this.parent.old_password);
|
||||
var tmp = angular.copy(this.parent.plain_credential);
|
||||
|
||||
//@FIXME Your shared credentials are not updated properly
|
||||
if (tmp.hasOwnProperty('shared_key') && tmp.shared_key !== null) {
|
||||
if (tmp.hasOwnProperty('shared_key') && tmp.shared_key !== null && !skipSharingKey) {
|
||||
var shared_key = EncryptService.decryptString(angular.copy(tmp.shared_key)).trim();
|
||||
tmp.shared_key = EncryptService.encryptString(angular.copy(shared_key), this.parent.new_password);
|
||||
tmp.set_share_key = true;
|
||||
|
|
|
@ -48,7 +48,7 @@ var PassmanImporter = PassmanImporter || {};
|
|||
_credential.url = row.url;
|
||||
_credential.tags = (row.grouping) ? [{text: row.grouping}] : [];
|
||||
_credential.description = row.extra;
|
||||
if(_credential.label){
|
||||
if(_credential.label && _credential.label !== "undefined"){
|
||||
credential_list.push(_credential);
|
||||
}
|
||||
var progress = {
|
||||
|
@ -58,7 +58,7 @@ var PassmanImporter = PassmanImporter || {};
|
|||
};
|
||||
this.call_progress(progress);
|
||||
}
|
||||
this.call_then(credential_list)
|
||||
this.call_then(credential_list);
|
||||
});
|
||||
};
|
||||
})(window, $, PassmanImporter);
|
File diff suppressed because one or more lines are too long
|
@ -74,6 +74,7 @@ script('passman', 'app/directives/ngenter');
|
|||
script('passman', 'app/directives/autoscroll');
|
||||
script('passman', 'app/directives/clickselect');
|
||||
script('passman', 'app/directives/colorfromstring');
|
||||
script('passman', 'app/directives/credentialcounter');
|
||||
script('passman', 'app/directives/clearbutton2');
|
||||
script('passman', 'importers/import-main');
|
||||
script('passman', 'importers/importer-keepasscsv');
|
||||
|
|
|
@ -108,17 +108,5 @@ $ciphers = openssl_get_cipher_methods();
|
|||
</option>
|
||||
</select>
|
||||
</p>
|
||||
<p>
|
||||
|
||||
<label for="server_side_encryption">Server side encryption
|
||||
method:</label>
|
||||
<select name="server_side_encryption2" id="server_side_encryption2">
|
||||
<?php
|
||||
foreach ($ciphers as $cipher) {
|
||||
print '<option value="' . $cipher . '">' . $cipher . '</option>';
|
||||
}
|
||||
?>
|
||||
</select> (Not working atm. OpenSSL has no equivalent of <code>mcrypt_get_key_size()</code>)
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
<div class="tab_container share_credential" ng-show="currentTab">
|
||||
<div ng-include="currentTab.url"></div>
|
||||
|
||||
<button ng-click="applyShare()">{{ 'share' | translate}}</button>
|
||||
<button ng-click="applyShare()" ng-disabled="!share_settings.linkSharing.enabled || share_settings.credentialSharedWithUserAndGroup.length > 0">{{ 'share' | translate}}</button>
|
||||
<button ng-click="cancel()">{{ 'cancel' | translate}}</button>
|
||||
<button class="btn btn-danger" ng-click="unshareCredential(storedCredential)">{{ 'unshare' | translate}}</button>
|
||||
</div>
|
||||
|
|
|
@ -10,21 +10,18 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="title" ng-if="delete_time">
|
||||
{{ 'deleted.since' | translate }}:
|
||||
<span ng-if="delete_time == 1">All time</span>
|
||||
<span ng-if="delete_time > 1">{{delete_time | date:'dd-MM-yyyy @ HH:mm:ss'}}</span>
|
||||
|
||||
</span>
|
||||
<div class="actions creatable">
|
||||
<span ng-click="addCredential()" class="button new">
|
||||
<span >+</span></span>
|
||||
</div>
|
||||
<div class="title" ng-show="filtered_credentials.length > 0" translate="number.filtered"
|
||||
translate-values="{number_filtered: filtered_credentials.length, credential_number: active_vault.credentials.length - 1}"
|
||||
>
|
||||
<div class="title" credential-counter="filtered_credentials" vault="active_vault" delete-time="delete_time" filters="filterOptions"></div>
|
||||
<!--<span class="title" ng-if="delete_time"><br />
|
||||
{{ 'deleted.since' | translate }}:
|
||||
<span ng-if="delete_time == 1">All time</span>
|
||||
<span ng-if="delete_time > 1">{{delete_time | date:'dd-MM-yyyy @ HH:mm:ss'}}</span>
|
||||
|
||||
</div>
|
||||
</span> -->
|
||||
<div class="searchboxContainer" ng-init="filterOptionShown = false;" off-click="filterOptionShown = false;">
|
||||
<input type="text" ng-model="filterOptions.filterText" class="searchbox" id="searchBox"
|
||||
placeholder="{{'search.credential' | translate}}" select-on-click clear-btn ng-click="filterOptionShown = true;">
|
||||
|
|
Loading…
Reference in a new issue