mirror of
https://github.com/nextcloud/passman.git
synced 2025-11-10 14:11:06 +08:00
Merge branch 'master' into fix-docx-file-handling
This commit is contained in:
commit
c28afd1b0b
13 changed files with 401 additions and 172 deletions
|
|
@ -58,14 +58,17 @@ return [
|
||||||
['name' => 'share#getPendingRequests', 'url' => '/api/v2/sharing/pending', 'verb' => 'GET'],
|
['name' => 'share#getPendingRequests', 'url' => '/api/v2/sharing/pending', 'verb' => 'GET'],
|
||||||
['name' => 'share#deleteShareRequest', 'url' => '/api/v2/sharing/decline/{share_request_id}', 'verb' => 'DELETE'],
|
['name' => 'share#deleteShareRequest', 'url' => '/api/v2/sharing/decline/{share_request_id}', 'verb' => 'DELETE'],
|
||||||
['name' => 'share#getVaultItems', 'url' => '/api/v2/sharing/vault/{vault_guid}/get', 'verb' => 'GET'],
|
['name' => 'share#getVaultItems', 'url' => '/api/v2/sharing/vault/{vault_guid}/get', 'verb' => 'GET'],
|
||||||
|
['name' => 'share#getVaultAclEntries', 'url' => '/api/v2/sharing/vault/{vault_guid}/acl', 'verb' => 'GET'],
|
||||||
['name' => 'share#createPublicShare', 'url' => '/api/v2/sharing/public', 'verb' => 'POST'],
|
['name' => 'share#createPublicShare', 'url' => '/api/v2/sharing/public', 'verb' => 'POST'],
|
||||||
['name' => 'share#getPublicCredentialData', 'url' => '/api/v2/sharing/credential/{credential_guid}/public', 'verb' => 'GET'],
|
['name' => 'share#getPublicCredentialData', 'url' => '/api/v2/sharing/credential/{credential_guid}/public', 'verb' => 'GET'],
|
||||||
['name' => 'share#unshareCredential', 'url' => '/api/v2/sharing/credential/{item_guid}', 'verb' => 'DELETE'],
|
['name' => 'share#unshareCredential', 'url' => '/api/v2/sharing/credential/{item_guid}', 'verb' => 'DELETE'],
|
||||||
['name' => 'share#unshareCredentialFromUser', 'url' => '/api/v2/sharing/credential/{item_guid}/{user_id}', 'verb' => 'DELETE'],
|
['name' => 'share#unshareCredentialFromUser', 'url' => '/api/v2/sharing/credential/{item_guid}/{user_id}', 'verb' => 'DELETE'],
|
||||||
['name' => 'share#getRevisions', 'url' => '/api/v2/sharing/credential/{item_guid}/revisions', 'verb' => 'GET'],
|
['name' => 'share#getRevisions', 'url' => '/api/v2/sharing/credential/{item_guid}/revisions', 'verb' => 'GET'],
|
||||||
['name' => 'share#getItemAcl', 'url' => '/api/v2/sharing/credential/{item_guid}/acl', 'verb' => 'GET'],
|
['name' => 'share#getItemAcl', 'url' => '/api/v2/sharing/credential/{item_guid}/acl', 'verb' => 'GET'],
|
||||||
|
['name' => 'share#uploadFile', 'url' => '/api/v2/sharing/credential/{item_guid}/file', 'verb' => 'POST'],
|
||||||
['name' => 'share#getFile', 'url' => '/api/v2/sharing/credential/{item_guid}/file/{file_guid}', 'verb' => 'GET'],
|
['name' => 'share#getFile', 'url' => '/api/v2/sharing/credential/{item_guid}/file/{file_guid}', 'verb' => 'GET'],
|
||||||
['name' => 'share#updateSharedCredentialACL', 'url' => '/api/v2/sharing/credential/{item_guid}/acl', 'verb' => 'PATCH'],
|
['name' => 'share#updateSharedCredentialACL', 'url' => '/api/v2/sharing/credential/{item_guid}/acl', 'verb' => 'PATCH'],
|
||||||
|
['name' => 'share#updateSharedCredentialACLSharedKey', 'url' => '/api/v2/sharing/credential/{item_guid}/acl/shared_key', 'verb' => 'PATCH'],
|
||||||
['name' => 'internal#getAppVersion', 'url' => '/api/v2/version', 'verb' => 'GET'],
|
['name' => 'internal#getAppVersion', 'url' => '/api/v2/version', 'verb' => 'GET'],
|
||||||
|
|
||||||
//Settings
|
//Settings
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,10 @@ class FileController extends ApiController {
|
||||||
return new JSONResponse(array('ok' => empty($failed_file_ids), 'failed' => $failed_file_ids));
|
return new JSONResponse(array('ok' => empty($failed_file_ids), 'failed' => $failed_file_ids));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @NoAdminRequired
|
||||||
|
* @NoCSRFRequired
|
||||||
|
*/
|
||||||
public function updateFile($file_id, $file_data, $filename) {
|
public function updateFile($file_id, $file_data, $filename) {
|
||||||
try {
|
try {
|
||||||
$file = $this->fileService->getFile($file_id, $this->userId);
|
$file = $this->fileService->getFile($file_id, $this->userId);
|
||||||
|
|
|
||||||
|
|
@ -368,6 +368,20 @@ class ShareController extends ApiController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains the list of acl entries for credentials shared with this vault
|
||||||
|
*
|
||||||
|
* @NoAdminRequired
|
||||||
|
* @NoCSRFRequired
|
||||||
|
*/
|
||||||
|
public function getVaultAclEntries($vault_guid) {
|
||||||
|
try {
|
||||||
|
return new JSONResponse($this->shareService->getVaultAclList($this->userId->getUID(), $vault_guid));
|
||||||
|
} catch (\Exception $ex) {
|
||||||
|
return new NotFoundResponse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $share_request_id
|
* @param $share_request_id
|
||||||
* @return JSONResponse
|
* @return JSONResponse
|
||||||
|
|
@ -476,13 +490,55 @@ class ShareController extends ApiController {
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
return new NotFoundJSONResponse();
|
return new NotFoundJSONResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// $this->userId does not exist for anonymous share link downloads
|
||||||
$userId = ($this->userId) ? $this->userId->getUID() : null;
|
$userId = ($this->userId) ? $this->userId->getUID() : null;
|
||||||
$acl = $this->shareService->getACL($userId, $credential->getGuid());
|
$acl = $this->shareService->getACL($userId, $credential->getGuid());
|
||||||
if (!$acl->hasPermission(SharingACL::FILES)) {
|
|
||||||
return new NotFoundJSONResponse();
|
if ($acl->hasPermission(SharingACL::FILES)) {
|
||||||
} else {
|
// get file by guid and check if it is owned by the owner of the shared credential
|
||||||
return $this->fileService->getFileByGuid($file_guid);
|
return $this->fileService->getFileByGuid($file_guid, $credential->getUserId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return new NotFoundJSONResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $item_guid
|
||||||
|
* @param $data
|
||||||
|
* @param $filename
|
||||||
|
* @param $mimetype
|
||||||
|
* @param $size
|
||||||
|
* @return DataResponse|NotFoundJSONResponse|JSONResponse
|
||||||
|
* @throws \Exception
|
||||||
|
* @NoAdminRequired
|
||||||
|
* @NoCSRFRequired
|
||||||
|
*/
|
||||||
|
public function uploadFile($item_guid, $data, $filename, $mimetype, $size) {
|
||||||
|
try {
|
||||||
|
$credential = $this->credentialService->getCredentialByGUID($item_guid);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return new NotFoundJSONResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
// only check acl, if the uploading user is not the credential owner
|
||||||
|
if ($credential->getUserId() != $this->userId->getUID()) {
|
||||||
|
$acl = $this->shareService->getACL($this->userId->getUID(), $credential->getGuid());
|
||||||
|
if (!$acl->hasPermission(SharingACL::FILES)) {
|
||||||
|
return new DataResponse(['msg' => 'Not authorized'], Http::STATUS_UNAUTHORIZED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = array(
|
||||||
|
'filename' => $filename,
|
||||||
|
'size' => $size,
|
||||||
|
'mimetype' => $mimetype,
|
||||||
|
'file_data' => $data,
|
||||||
|
'user_id' => $credential->getUserId()
|
||||||
|
);
|
||||||
|
|
||||||
|
// save the file with the id of the user that owns the credential
|
||||||
|
return new JSONResponse($this->fileService->createFile($file, $credential->getUserId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -515,4 +571,18 @@ class ShareController extends ApiController {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $item_guid
|
||||||
|
* @param $shared_key
|
||||||
|
* @return JSONResponse
|
||||||
|
* @NoAdminRequired
|
||||||
|
* @NoCSRFRequired
|
||||||
|
*/
|
||||||
|
public function updateSharedCredentialACLSharedKey($item_guid, $shared_key) {
|
||||||
|
/** @var SharingACL $acl */
|
||||||
|
$acl = $this->shareService->getACL($this->userId->getUID(), $item_guid);
|
||||||
|
$acl->setSharedKey($shared_key);
|
||||||
|
return new JSONResponse($this->shareService->updateCredentialACL($acl)->jsonSerialize());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ class TranslationController extends ApiController {
|
||||||
'credential.recovered' => $this->trans->t('Credential recovered'),
|
'credential.recovered' => $this->trans->t('Credential recovered'),
|
||||||
'credential.destroyed' => $this->trans->t('Credential destroyed'),
|
'credential.destroyed' => $this->trans->t('Credential destroyed'),
|
||||||
'error.loading.file.perm' => $this->trans->t('Error downloading file, you probably have insufficient permissions'),
|
'error.loading.file.perm' => $this->trans->t('Error downloading file, you probably have insufficient permissions'),
|
||||||
|
'error.general' => $this->trans->t('An error occurred'),
|
||||||
|
|
||||||
// js/app/controllers/edit_credential.js
|
// js/app/controllers/edit_credential.js
|
||||||
'invalid.qr' => $this->trans->t('Invalid QR code'),
|
'invalid.qr' => $this->trans->t('Invalid QR code'),
|
||||||
|
|
|
||||||
|
|
@ -72,20 +72,18 @@
|
||||||
try {
|
try {
|
||||||
if (!_credential.shared_key) {
|
if (!_credential.shared_key) {
|
||||||
_credential = CredentialService.decryptCredential(angular.copy(_credential));
|
_credential = CredentialService.decryptCredential(angular.copy(_credential));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
var enc_key = EncryptService.decryptString(_credential.shared_key);
|
var enc_key = EncryptService.decryptString(_credential.shared_key);
|
||||||
_credential = ShareService.decryptSharedCredential(angular.copy(_credential), enc_key);
|
_credential = ShareService.decryptSharedCredential(angular.copy(_credential), enc_key);
|
||||||
}
|
}
|
||||||
_credential.tags_raw = _credential.tags;
|
_credential.tags_raw = _credential.tags;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
||||||
NotificationService.showNotification($translate.instant('error.decrypt'), 5000);
|
NotificationService.showNotification($translate.instant('error.decrypt'), 5000);
|
||||||
|
console.error(e);
|
||||||
//$rootScope.$broadcast('logout');
|
//$rootScope.$broadcast('logout');
|
||||||
//SettingsService.setSetting('defaultVaultPass', null);
|
//SettingsService.setSetting('defaultVaultPass', null);
|
||||||
//.setSetting('defaultVault', null);
|
//.setSetting('defaultVault', null);
|
||||||
//$location.path('/')
|
//$location.path('/')
|
||||||
|
|
||||||
}
|
}
|
||||||
_credentials[i] = _credential;
|
_credentials[i] = _credential;
|
||||||
}
|
}
|
||||||
|
|
@ -181,10 +179,10 @@
|
||||||
|
|
||||||
private_key = ShareService.rsaPrivateKeyFromPEM(private_key);
|
private_key = ShareService.rsaPrivateKeyFromPEM(private_key);
|
||||||
/** global: forge */
|
/** global: forge */
|
||||||
crypted_shared_key = private_key.decrypt(forge.util.decode64(crypted_shared_key));
|
const decrypted_shared_key = private_key.decrypt(forge.util.decode64(crypted_shared_key));
|
||||||
crypted_shared_key = EncryptService.encryptString(crypted_shared_key);
|
const vault_key_encrypted_shared_key = EncryptService.encryptString(decrypted_shared_key);
|
||||||
|
|
||||||
ShareService.saveSharingRequest(share_request, crypted_shared_key).then(function () {
|
ShareService.saveSharingRequest(share_request, vault_key_encrypted_shared_key).then(function () {
|
||||||
var idx = $scope.incoming_share_requests.indexOf(share_request);
|
var idx = $scope.incoming_share_requests.indexOf(share_request);
|
||||||
$scope.incoming_share_requests.splice(idx, 1);
|
$scope.incoming_share_requests.splice(idx, 1);
|
||||||
var active_share_requests = false;
|
var active_share_requests = false;
|
||||||
|
|
@ -261,54 +259,62 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
var notification;
|
var notification;
|
||||||
$scope.deleteCredential = function (credential) {
|
$scope.deleteCredential = function (decrypted_credential) {
|
||||||
var _credential = angular.copy(credential);
|
let _credential = angular.copy(decrypted_credential);
|
||||||
try {
|
|
||||||
_credential = CredentialService.decryptCredential(_credential);
|
|
||||||
} catch (e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
_credential.delete_time = new Date().getTime() / 1000;
|
_credential.delete_time = new Date().getTime() / 1000;
|
||||||
for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
|
|
||||||
if ($scope.active_vault.credentials[i].credential_id === credential.credential_id) {
|
|
||||||
$scope.active_vault.credentials[i].delete_time = _credential.delete_time;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$scope.closeSelected();
|
$scope.closeSelected();
|
||||||
if (notification) {
|
if (notification) {
|
||||||
NotificationService.hideNotification(notification);
|
NotificationService.hideNotification(notification);
|
||||||
}
|
}
|
||||||
var key = CredentialService.getSharedKeyFromCredential(_credential);
|
|
||||||
CredentialService.updateCredential(_credential, false, key).then(function () {
|
const key = CredentialService.getSharedKeyFromCredential(_credential);
|
||||||
|
CredentialService.updateCredential(_credential, false, key).then(function (response) {
|
||||||
|
decrypted_credential.delete_time = _credential.delete_time;
|
||||||
|
for (let i = 0; i < $scope.active_vault.credentials.length; i++) {
|
||||||
|
if ($scope.active_vault.credentials[i].credential_id === _credential.credential_id) {
|
||||||
|
$scope.active_vault.credentials[i].delete_time = _credential.delete_time;
|
||||||
|
}
|
||||||
|
}
|
||||||
notification = NotificationService.showNotification($translate.instant('credential.deleted'), 5000);
|
notification = NotificationService.showNotification($translate.instant('credential.deleted'), 5000);
|
||||||
|
}, function (error) {
|
||||||
|
if (error.data.msg) {
|
||||||
|
NotificationService.showNotification(error.data.msg, 5000);
|
||||||
|
} else {
|
||||||
|
NotificationService.showNotification($translate.instant('error.general'), 5000);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.recoverCredential = function (credential) {
|
$scope.recoverCredential = function (decrypted_credential) {
|
||||||
var _credential = angular.copy(credential);
|
let _credential = angular.copy(decrypted_credential);
|
||||||
try {
|
|
||||||
_credential = CredentialService.decryptCredential(_credential);
|
|
||||||
} catch (e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
|
|
||||||
if ($scope.active_vault.credentials[i].credential_id === credential.credential_id) {
|
|
||||||
$scope.active_vault.credentials[i].delete_time = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_credential.delete_time = 0;
|
_credential.delete_time = 0;
|
||||||
|
|
||||||
$scope.closeSelected();
|
$scope.closeSelected();
|
||||||
if (notification) {
|
if (notification) {
|
||||||
NotificationService.hideNotification(notification);
|
NotificationService.hideNotification(notification);
|
||||||
}
|
}
|
||||||
var key = CredentialService.getSharedKeyFromCredential(_credential);
|
|
||||||
CredentialService.updateCredential(_credential, false, key).then(function () {
|
const key = CredentialService.getSharedKeyFromCredential(_credential);
|
||||||
|
CredentialService.updateCredential(_credential, false, key).then(function (response) {
|
||||||
|
decrypted_credential.delete_time = 0;
|
||||||
|
for (let i = 0; i < $scope.active_vault.credentials.length; i++) {
|
||||||
|
if ($scope.active_vault.credentials[i].credential_id === _credential.credential_id) {
|
||||||
|
$scope.active_vault.credentials[i].delete_time = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
NotificationService.showNotification($translate.instant('credential.recovered'), 5000);
|
NotificationService.showNotification($translate.instant('credential.recovered'), 5000);
|
||||||
|
}, function (error) {
|
||||||
|
if (error.data.msg) {
|
||||||
|
NotificationService.showNotification(error.data.msg, 5000);
|
||||||
|
} else {
|
||||||
|
NotificationService.showNotification($translate.instant('error.general'), 5000);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.destroyCredential = function (credential) {
|
$scope.destroyCredential = function (credential) {
|
||||||
var _credential = angular.copy(credential);
|
const _credential = angular.copy(credential);
|
||||||
CredentialService.destroyCredential(_credential.guid).then(function () {
|
CredentialService.destroyCredential(_credential.guid).then(function () {
|
||||||
for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
|
for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
|
||||||
if ($scope.active_vault.credentials[i].credential_id === credential.credential_id) {
|
if ($scope.active_vault.credentials[i].credential_id === credential.credential_id) {
|
||||||
|
|
@ -317,6 +323,12 @@
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}, function (error) {
|
||||||
|
if (error.data.msg) {
|
||||||
|
NotificationService.showNotification(error.data.msg, 5000);
|
||||||
|
} else {
|
||||||
|
NotificationService.showNotification($translate.instant('error.general'), 5000);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -161,26 +161,22 @@
|
||||||
$scope.selected_field_type = 'text';
|
$scope.selected_field_type = 'text';
|
||||||
_field.secret = (_field.field_type === 'password');
|
_field.secret = (_field.field_type === 'password');
|
||||||
if(_field.field_type === 'file'){
|
if(_field.field_type === 'file'){
|
||||||
var key = false;
|
const key = CredentialService.getSharedKeyFromCredential($scope.storedCredential);
|
||||||
var _file = $scope.new_custom_field.value;
|
const file = $scope.new_custom_field.value;
|
||||||
if (!$scope.storedCredential.hasOwnProperty('acl') && $scope.storedCredential.hasOwnProperty('shared_key')) {
|
|
||||||
|
|
||||||
if ($scope.storedCredential.shared_key) {
|
const callback = function (result) {
|
||||||
key = EncryptService.decryptString(angular.copy($scope.storedCredential.shared_key));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($scope.storedCredential.hasOwnProperty('acl')) {
|
|
||||||
key = EncryptService.decryptString(angular.copy($scope.storedCredential.acl.shared_key));
|
|
||||||
}
|
|
||||||
|
|
||||||
FileService.uploadFile(_file, key).then(function (result) {
|
|
||||||
delete result.file_data;
|
delete result.file_data;
|
||||||
result.filename = EncryptService.decryptString(result.filename, key);
|
result.filename = EncryptService.decryptString(result.filename, key);
|
||||||
_field.value = result;
|
_field.value = result;
|
||||||
$scope.storedCredential.custom_fields.push(_field);
|
$scope.storedCredential.custom_fields.push(_field);
|
||||||
$scope.new_custom_field = angular.copy(_customField);
|
$scope.new_custom_field = angular.copy(_customField);
|
||||||
});
|
};
|
||||||
|
|
||||||
|
if (key) {
|
||||||
|
ShareService.uploadSharedFile($scope.storedCredential, file, key).then(callback);
|
||||||
|
} else {
|
||||||
|
FileService.uploadFile(file).then(callback);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$scope.storedCredential.custom_fields.push(_field);
|
$scope.storedCredential.custom_fields.push(_field);
|
||||||
$scope.new_custom_field = angular.copy(_customField);
|
$scope.new_custom_field = angular.copy(_customField);
|
||||||
|
|
@ -229,11 +225,17 @@
|
||||||
data: file.data
|
data: file.data
|
||||||
};
|
};
|
||||||
|
|
||||||
FileService.uploadFile(_file, key).then(function (result) {
|
const callback = function (result) {
|
||||||
delete result.file_data;
|
delete result.file_data;
|
||||||
result.filename = EncryptService.decryptString(result.filename, key);
|
result.filename = EncryptService.decryptString(result.filename, key);
|
||||||
$scope.storedCredential.files.push(result);
|
$scope.storedCredential.files.push(result);
|
||||||
});
|
};
|
||||||
|
|
||||||
|
if (key) {
|
||||||
|
ShareService.uploadSharedFile($scope.storedCredential, _file, key).then(callback);
|
||||||
|
} else {
|
||||||
|
FileService.uploadFile(_file).then(callback);
|
||||||
|
}
|
||||||
|
|
||||||
$scope.$digest();
|
$scope.$digest();
|
||||||
};
|
};
|
||||||
|
|
@ -329,31 +331,17 @@
|
||||||
|
|
||||||
$scope.updateExistingListWithCredential(new_cred);
|
$scope.updateExistingListWithCredential(new_cred);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
let _credential = angular.copy($scope.storedCredential);
|
||||||
var key, _credential;
|
const key = CredentialService.getSharedKeyFromCredential($scope.storedCredential);
|
||||||
if (!$scope.storedCredential.hasOwnProperty('acl') && $scope.storedCredential.hasOwnProperty('shared_key')) {
|
|
||||||
|
|
||||||
if ($scope.storedCredential.shared_key) {
|
|
||||||
key = EncryptService.decryptString(angular.copy($scope.storedCredential.shared_key));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($scope.storedCredential.hasOwnProperty('acl')) {
|
|
||||||
key = EncryptService.decryptString(angular.copy($scope.storedCredential.acl.shared_key));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key) {
|
if (key) {
|
||||||
_credential = ShareService.encryptSharedCredential($scope.storedCredential, key);
|
_credential = ShareService.encryptSharedCredential($scope.storedCredential, key);
|
||||||
} else {
|
|
||||||
_credential = angular.copy($scope.storedCredential);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delete _credential.shared_key;
|
delete _credential.shared_key;
|
||||||
var _useKey = (key != null);
|
const _useKey = (key != null);
|
||||||
var regex = /(<([^>]+)>)/ig;
|
const regex = /(<([^>]+)>)/ig;
|
||||||
if(_credential.description && _credential.description !== "") {
|
if(_credential.description && _credential.description !== "") {
|
||||||
_credential.description = _credential.description.replace(regex, "");
|
_credential.description = _credential.description.replace(regex, "");
|
||||||
}
|
}
|
||||||
|
|
@ -373,17 +361,17 @@
|
||||||
if (!credential.shared_key) {
|
if (!credential.shared_key) {
|
||||||
credential = CredentialService.decryptCredential(credential);
|
credential = CredentialService.decryptCredential(credential);
|
||||||
} else {
|
} else {
|
||||||
var enc_key = EncryptService.decryptString(credential.shared_key);
|
const enc_key = CredentialService.getSharedKeyFromCredential($scope.storedCredential);
|
||||||
credential = ShareService.decryptSharedCredential(credential, enc_key);
|
credential = ShareService.decryptSharedCredential(credential, enc_key);
|
||||||
}
|
}
|
||||||
credential.tags_raw = credential.tags;
|
credential.tags_raw = credential.tags;
|
||||||
|
|
||||||
var found=false;
|
let found = false;
|
||||||
var credList=$rootScope.vaultCache[$scope.active_vault.guid].credentials;
|
let credList = $rootScope.vaultCache[$scope.active_vault.guid].credentials;
|
||||||
for (var i = 0; i < credList.length; i++) {
|
for (let i = 0; i < credList.length; i++) {
|
||||||
if (credList[i].credential_id === credential.credential_id) {
|
if (credList[i].credential_id === credential.credential_id) {
|
||||||
$rootScope.vaultCache[$scope.active_vault.guid].credentials[i]=credential;
|
$rootScope.vaultCache[$scope.active_vault.guid].credentials[i] = credential;
|
||||||
found=true;
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -391,7 +379,6 @@
|
||||||
$rootScope.vaultCache[$scope.active_vault.guid].credentials.push(credential);
|
$rootScope.vaultCache[$scope.active_vault.guid].credentials.push(credential);
|
||||||
}
|
}
|
||||||
$rootScope.$broadcast('push_decrypted_credential_to_list', credential);
|
$rootScope.$broadcast('push_decrypted_credential_to_list', credential);
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
NotificationService.showNotification($translate.instant('error.decrypt'), 5000);
|
NotificationService.showNotification($translate.instant('error.decrypt'), 5000);
|
||||||
console.log(e);
|
console.log(e);
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var key_strengths = [
|
const key_strengths = [
|
||||||
'password.poor',
|
'password.poor',
|
||||||
'password.poor',
|
'password.poor',
|
||||||
'password.weak',
|
'password.weak',
|
||||||
|
|
@ -86,7 +86,7 @@
|
||||||
$scope.required_score = {'strength': translation};
|
$scope.required_score = {'strength': translation};
|
||||||
});
|
});
|
||||||
|
|
||||||
var btn_txt = $translate.instant('bookmarklet.text');
|
const btn_txt = $translate.instant('bookmarklet.text');
|
||||||
var http = location.protocol, slashes = http.concat("//"),
|
var http = location.protocol, slashes = http.concat("//"),
|
||||||
host = slashes.concat(window.location.hostname + ":" + window.location.port),
|
host = slashes.concat(window.location.hostname + ":" + window.location.port),
|
||||||
complete = host + location.pathname;
|
complete = host + location.pathname;
|
||||||
|
|
@ -94,7 +94,7 @@
|
||||||
|
|
||||||
|
|
||||||
$scope.saveVaultSettings = function () {
|
$scope.saveVaultSettings = function () {
|
||||||
var _vault = $scope.active_vault;
|
let _vault = $scope.active_vault;
|
||||||
_vault.name = $scope.new_vault_name;
|
_vault.name = $scope.new_vault_name;
|
||||||
_vault.vault_settings = angular.copy($scope.vault_settings);
|
_vault.vault_settings = angular.copy($scope.vault_settings);
|
||||||
VaultService.updateVault(_vault).then(function () {
|
VaultService.updateVault(_vault).then(function () {
|
||||||
|
|
@ -236,19 +236,9 @@
|
||||||
done: 0,
|
done: 0,
|
||||||
total: _selected_credentials.length
|
total: _selected_credentials.length
|
||||||
};
|
};
|
||||||
var changeCredential = function (index, oldVaultPass, newVaultPass) {
|
const changeCredential = function (index, oldVaultPass, newVaultPass) {
|
||||||
var usedKey = oldVaultPass;
|
const next_credential_callback = function () {
|
||||||
|
const percent = index / _selected_credentials.length * 100;
|
||||||
if (_selected_credentials[index].hasOwnProperty('shared_key')) {
|
|
||||||
if (_selected_credentials[index].shared_key) {
|
|
||||||
usedKey = EncryptService.decryptString(angular.copy(_selected_credentials[index].shared_key), oldVaultPass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CredentialService.reencryptCredential(_selected_credentials[index].guid, usedKey, newVaultPass).progress(function (data) {
|
|
||||||
$scope.cur_state = data;
|
|
||||||
}).then(function () {
|
|
||||||
var percent = index / _selected_credentials.length * 100;
|
|
||||||
$scope.change_pw = {
|
$scope.change_pw = {
|
||||||
percent: percent,
|
percent: percent,
|
||||||
done: index + 1,
|
done: index + 1,
|
||||||
|
|
@ -260,14 +250,31 @@
|
||||||
vault.private_sharing_key = EncryptService.decryptString(angular.copy(vault.private_sharing_key), oldVaultPass);
|
vault.private_sharing_key = EncryptService.decryptString(angular.copy(vault.private_sharing_key), oldVaultPass);
|
||||||
vault.private_sharing_key = EncryptService.encryptString(vault.private_sharing_key, newVaultPass);
|
vault.private_sharing_key = EncryptService.encryptString(vault.private_sharing_key, newVaultPass);
|
||||||
VaultService.updateSharingKeys(vault).then(function () {
|
VaultService.updateSharingKeys(vault).then(function () {
|
||||||
$rootScope.$broadcast('logout');
|
VaultService.reEncryptACLSharingKeys(vault, oldVaultPass, newVaultPass, EncryptService).then(function () {
|
||||||
NotificationService.showNotification($translate.instant('login.new.pass'), 5000);
|
$rootScope.$broadcast('logout');
|
||||||
|
NotificationService.showNotification($translate.instant('login.new.pass'), 5000);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
|
if (_selected_credentials[index].shared_key) {
|
||||||
|
// only re-encrypt the shared key, if the credential is shared and not encrypted with the vault key like default credentials
|
||||||
|
CredentialService.getCredential(_selected_credentials[index].guid).then((function (credential) {
|
||||||
|
const decrypted_shared_key = EncryptService.decryptString(angular.copy(credential.shared_key), oldVaultPass);
|
||||||
|
let _credential = angular.copy(credential);
|
||||||
|
_credential.set_share_key = true;
|
||||||
|
_credential.skip_revision = true;
|
||||||
|
_credential.shared_key = EncryptService.encryptString(decrypted_shared_key, newVaultPass);
|
||||||
|
CredentialService.updateCredential(_credential, true).then(next_credential_callback);
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
CredentialService.reencryptCredential(_selected_credentials[index].guid, oldVaultPass, newVaultPass).progress(function (data) {
|
||||||
|
$scope.cur_state = data;
|
||||||
|
}).then(next_credential_callback);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
changeCredential(0, VaultService.getActiveVault().vaultKey, newVaultPass);
|
changeCredential(0, VaultService.getActiveVault().vaultKey, newVaultPass);
|
||||||
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -276,18 +283,23 @@
|
||||||
$scope.delete_vault = function () {
|
$scope.delete_vault = function () {
|
||||||
if ($scope.confirm_vault_delete && $scope.delete_vault_password === VaultService.getActiveVault().vaultKey) {
|
if ($scope.confirm_vault_delete && $scope.delete_vault_password === VaultService.getActiveVault().vaultKey) {
|
||||||
getCurrentVaultCredentials(function (vault) {
|
getCurrentVaultCredentials(function (vault) {
|
||||||
var credentials = vault.credentials;
|
const credentials = vault.credentials;
|
||||||
$scope.remove_pw = {
|
$scope.remove_pw = {
|
||||||
percent: 0,
|
percent: 0,
|
||||||
done: 0,
|
done: 0,
|
||||||
total: vault.credentials.length,
|
total: vault.credentials.length,
|
||||||
};
|
};
|
||||||
|
|
||||||
var file_ids = [];
|
const file_ids = [];
|
||||||
for (const credential of credentials) {
|
for (const credential of credentials) {
|
||||||
var decryptedFiles = JSON.parse(EncryptService.decryptString(angular.copy(credential.files), VaultService.getActiveVault().vaultKey));
|
try {
|
||||||
for (const file of decryptedFiles) {
|
const enc_key = CredentialService.getSharedKeyFromCredential(credential);
|
||||||
file_ids.push(file.file_id);
|
const decryptedFiles = JSON.parse(EncryptService.decryptString(angular.copy(credential.files), enc_key));
|
||||||
|
for (const file of decryptedFiles) {
|
||||||
|
file_ids.push(file.file_id);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -278,7 +278,7 @@
|
||||||
$scope.$digest();
|
$scope.$digest();
|
||||||
})
|
})
|
||||||
.then(function (result) {
|
.then(function (result) {
|
||||||
$scope.share_settings.cypher_progress.times.push({
|
$scope.share_settings.cypher_progress.times.push({
|
||||||
time: ((new Date().getTime() / 1000) - start),
|
time: ((new Date().getTime() / 1000) - start),
|
||||||
user: data[0].user_id
|
user: data[0].user_id
|
||||||
});
|
});
|
||||||
|
|
@ -320,7 +320,7 @@
|
||||||
$scope.share_settings.upload_progress.total = 0;
|
$scope.share_settings.upload_progress.total = 0;
|
||||||
//Credential is already shared
|
//Credential is already shared
|
||||||
if ($scope.storedCredential.shared_key && $scope.storedCredential.shared_key !== '' && $scope.storedCredential.shared_key !== null) {
|
if ($scope.storedCredential.shared_key && $scope.storedCredential.shared_key !== '' && $scope.storedCredential.shared_key !== null) {
|
||||||
var enc_key = EncryptService.decryptString(angular.copy($scope.storedCredential.shared_key));
|
var enc_key = EncryptService.decryptString(angular.copy($scope.storedCredential.shared_key));
|
||||||
if ($scope.share_settings.linkSharing.enabled) {
|
if ($scope.share_settings.linkSharing.enabled) {
|
||||||
var expire_time = new Date(angular.copy($scope.share_settings.linkSharing.settings.expire_time)).getTime() / 1000;
|
var expire_time = new Date(angular.copy($scope.share_settings.linkSharing.settings.expire_time)).getTime() / 1000;
|
||||||
var shareObj = {
|
var shareObj = {
|
||||||
|
|
@ -355,28 +355,31 @@
|
||||||
$scope.sharing_complete = true;
|
$scope.sharing_complete = true;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
ShareService.generateSharedKey(20).then(function (key) {
|
ShareService.generateSharedKey(20).then(function (generated_shared_key) {
|
||||||
|
|
||||||
|
// copy complete credential to encryptedSharedCredential where it can be safely re-encrypted
|
||||||
var encryptedSharedCredential = angular.copy($scope.storedCredential);
|
var encryptedSharedCredential = angular.copy($scope.storedCredential);
|
||||||
var old_key = VaultService.getActiveVault().vaultKey;
|
var vault_key = VaultService.getActiveVault().vaultKey;
|
||||||
|
|
||||||
CredentialService.reencryptCredential(encryptedSharedCredential.guid, old_key, key).progress(function () {
|
CredentialService
|
||||||
}).then(function (data) {
|
.reencryptCredential(encryptedSharedCredential.guid, vault_key, generated_shared_key)
|
||||||
var _credential = data.cryptogram;
|
.progress(function () {})
|
||||||
_credential.set_share_key = true;
|
.then(function (data) {
|
||||||
_credential.skip_revision = true;
|
var _credential = data.cryptogram;
|
||||||
_credential.shared_key = EncryptService.encryptString(key);
|
_credential.set_share_key = true;
|
||||||
CredentialService.updateCredential(_credential, true).then(function () {
|
_credential.skip_revision = true;
|
||||||
$scope.storedCredential.shared_key = _credential.shared_key;
|
_credential.shared_key = EncryptService.encryptString(generated_shared_key);
|
||||||
NotificationService.showNotification($translate.instant('credential.shared'), 4000);
|
CredentialService.updateCredential(_credential, true).then(function () {
|
||||||
$scope.sharing_complete = true;
|
$scope.storedCredential.shared_key = _credential.shared_key;
|
||||||
});
|
NotificationService.showNotification($translate.instant('credential.shared'), 4000);
|
||||||
});
|
$scope.sharing_complete = true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
var list = $scope.share_settings.credentialSharedWithUserAndGroup;
|
var list = $scope.share_settings.credentialSharedWithUserAndGroup;
|
||||||
for (var i = 0; i < list.length; i++) {
|
for (var i = 0; i < list.length; i++) {
|
||||||
if (list[i].type === "user") {
|
if (list[i].type === "user") {
|
||||||
$scope.applyShareToUser(list[i], key);
|
$scope.applyShareToUser(list[i], generated_shared_key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -390,7 +393,7 @@
|
||||||
expire_views: $scope.share_settings.linkSharing.settings.expire_views
|
expire_views: $scope.share_settings.linkSharing.settings.expire_views
|
||||||
};
|
};
|
||||||
ShareService.createPublicSharedCredential(shareObj).then(function () {
|
ShareService.createPublicSharedCredential(shareObj).then(function () {
|
||||||
var hash = window.btoa($scope.storedCredential.guid + '<::>' + key);
|
var hash = window.btoa($scope.storedCredential.guid + '<::>' + generated_shared_key);
|
||||||
$scope.share_link = getShareLink(hash);
|
$scope.share_link = getShareLink(hash);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -85,17 +85,13 @@
|
||||||
return _encryptedFields;
|
return _encryptedFields;
|
||||||
},
|
},
|
||||||
updateCredential: function (credential, skipEncryption, key) {
|
updateCredential: function (credential, skipEncryption, key) {
|
||||||
var _credential = angular.copy(credential);
|
let _credential = angular.copy(credential);
|
||||||
if (!skipEncryption) {
|
if (!skipEncryption) {
|
||||||
for (var i = 0; i < _encryptedFields.length; i++) {
|
_credential = this.encryptCredential(credential, key);
|
||||||
var field = _encryptedFields[i];
|
|
||||||
var fieldValue = angular.copy(credential[field]);
|
|
||||||
_credential[field] = EncryptService.encryptString(JSON.stringify(fieldValue), key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_credential.expire_time = new Date(angular.copy(credential.expire_time)).getTime() / 1000;
|
_credential.expire_time = new Date(angular.copy(credential.expire_time)).getTime() / 1000;
|
||||||
|
|
||||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/credentials/' + credential.guid);
|
const queryUrl = OC.generateUrl('apps/passman/api/v2/credentials/' + credential.guid);
|
||||||
return $http.patch(queryUrl, _credential).then(function (response) {
|
return $http.patch(queryUrl, _credential).then(function (response) {
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
return response.data;
|
return response.data;
|
||||||
|
|
@ -145,13 +141,13 @@
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Error decrypting credential:', credential);
|
console.error('Error decrypting credential:', credential);
|
||||||
|
console.error('Error decrypting credential field:', field);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
credential[field] = JSON.parse(field_decrypted_value);
|
credential[field] = JSON.parse(field_decrypted_value);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('Field' + field + ' in ' + credential.label + ' could not be parsed! Value:' + fieldValue);
|
console.warn('Field' + field + ' in ' + credential.label + ' could not be parsed! Value:' + fieldValue);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -215,23 +211,39 @@
|
||||||
var promise_credential_update = function () {
|
var promise_credential_update = function () {
|
||||||
service.getCredential(credential_guid).then((function (credential) {
|
service.getCredential(credential_guid).then((function (credential) {
|
||||||
this.parent.plain_credential = service.decryptCredential(credential, this.parent.old_password);
|
this.parent.plain_credential = service.decryptCredential(credential, this.parent.old_password);
|
||||||
var tmp = angular.copy(this.parent.plain_credential);
|
var plain_credential = angular.copy(this.parent.plain_credential);
|
||||||
|
|
||||||
if (tmp.hasOwnProperty('shared_key') && tmp.shared_key !== null && tmp.shared_key !== '' && !skipSharingKey) {
|
if (
|
||||||
var shared_key = EncryptService.decryptString(angular.copy(tmp.shared_key)).trim();
|
plain_credential.hasOwnProperty('shared_key') &&
|
||||||
tmp.shared_key = EncryptService.encryptString(angular.copy(shared_key), this.parent.new_password);
|
plain_credential.shared_key !== null &&
|
||||||
tmp.set_share_key = true;
|
plain_credential.shared_key !== '' &&
|
||||||
tmp.skip_revision = true;
|
!skipSharingKey
|
||||||
this.parent.new_password = shared_key;
|
) {
|
||||||
|
// re-encrypt the credential.shared_key with the new password
|
||||||
|
// (e.g. re-encrypt from vault_key to generated_shared_key)
|
||||||
|
const decrypted_credential_shared_key = EncryptService.decryptString(angular.copy(plain_credential.shared_key)).trim();
|
||||||
|
plain_credential.shared_key = EncryptService.encryptString(
|
||||||
|
angular.copy(decrypted_credential_shared_key),
|
||||||
|
this.parent.new_password
|
||||||
|
);
|
||||||
|
plain_credential.set_share_key = true;
|
||||||
|
plain_credential.skip_revision = true;
|
||||||
|
|
||||||
|
// todo: temporary comment out this Brantje code line as is looks pointless to set the
|
||||||
|
// new encryption key to the decrypted_credential_shared_key
|
||||||
|
// this.parent.new_password = decrypted_credential_shared_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.parent.new_credential_cryptogram = service.encryptCredential(tmp, this.parent.new_password);
|
// before: re-encryption with the now out-commented decrypted_credential_shared_key if the credential has one
|
||||||
|
// now: re-encryption with the original parent.new_password (e.g. generated_shared_key)
|
||||||
|
this.parent.new_credential_cryptogram = service.encryptCredential(plain_credential, this.parent.new_password);
|
||||||
this.call_progress(new progress_datatype(1, 2, 'credential'));
|
this.call_progress(new progress_datatype(1, 2, 'credential'));
|
||||||
|
|
||||||
// Save data
|
// Save data
|
||||||
this.parent.new_credential_cryptogram.skip_revision = true;
|
this.parent.new_credential_cryptogram.skip_revision = true;
|
||||||
service.updateCredential(this.parent.new_credential_cryptogram, true).then((function () {
|
service.updateCredential(this.parent.new_credential_cryptogram, true).then((function () {
|
||||||
this.call_progress(new progress_datatype(2, 2, 'credential'));
|
this.call_progress(new progress_datatype(2, 2, 'credential'));
|
||||||
|
// transfer plain and encrypted credential to the next promise in the complete re-encryption task
|
||||||
this.call_then({
|
this.call_then({
|
||||||
plain_text: this.parent.plain_credential,
|
plain_text: this.parent.plain_credential,
|
||||||
cryptogram: this.parent.new_credential_cryptogram
|
cryptogram: this.parent.new_credential_cryptogram
|
||||||
|
|
@ -241,36 +253,97 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
var promise_files_update = function () {
|
var promise_files_update = function () {
|
||||||
// Add the double of the files so we take encryption phase and upload to the server into the math
|
|
||||||
this.total = this.parent.plain_credential.files.length * 2; // Binded on credential finish upload
|
|
||||||
this.current = 0;
|
|
||||||
|
|
||||||
for (var i = 0; i < this.parent.plain_credential.files.length; i++) {
|
|
||||||
var _file = this.parent.plain_credential.files[i];
|
|
||||||
/* jshint ignore:start */
|
|
||||||
FileService.getFile(_file).then((function (fileData) {
|
|
||||||
//Decrypt with old key
|
|
||||||
fileData.filename = EncryptService.decryptString(fileData.filename, this.parent.old_password);
|
|
||||||
fileData.file_data = EncryptService.decryptString(fileData.file_data, this.parent.old_password);
|
|
||||||
|
|
||||||
this.current++;
|
|
||||||
|
|
||||||
this.call_progress(new progress_datatype(this.current, this.total, 'files'));
|
|
||||||
|
|
||||||
FileService.updateFile(fileData, this.parent.new_password).then((function () {
|
|
||||||
this.current++;
|
|
||||||
this.call_progress(new progress_datatype(this.current, this.total, 'files'));
|
|
||||||
if (this.current === this.total) {
|
|
||||||
this.call_then('All files has been updated');
|
|
||||||
}
|
|
||||||
}).bind(this));
|
|
||||||
}).bind(this));
|
|
||||||
/* jshint ignore:end */
|
|
||||||
}
|
|
||||||
if (this.parent.plain_credential.files.length === 0) {
|
if (this.parent.plain_credential.files.length === 0) {
|
||||||
this.call_progress(new progress_datatype(0, 0, 'files'));
|
this.call_progress(new progress_datatype(0, 0, 'files'));
|
||||||
this.call_then("No files to update");
|
this.call_then("No files to update");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.total = this.parent.plain_credential.files.length;
|
||||||
|
this.current = 0;
|
||||||
|
|
||||||
|
const files_workload = function () {
|
||||||
|
const check_next_callback = function () {
|
||||||
|
this.current++;
|
||||||
|
this.call_progress(new progress_datatype(this.current, this.total, 'files'));
|
||||||
|
|
||||||
|
if (this.current === this.total) {
|
||||||
|
this.call_then('All files has been updated');
|
||||||
|
} else {
|
||||||
|
setTimeout(files_workload.bind(this), 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const _file = this.parent.plain_credential.files[this.current];
|
||||||
|
/* jshint ignore:start */
|
||||||
|
FileService.getFile(_file).then((function (fileData) {
|
||||||
|
try {
|
||||||
|
//Decrypt with old key
|
||||||
|
fileData.filename = EncryptService.decryptString(fileData.filename, this.parent.old_password);
|
||||||
|
fileData.file_data = EncryptService.decryptString(fileData.file_data, this.parent.old_password);
|
||||||
|
|
||||||
|
FileService.updateFile(fileData, this.parent.new_password).then((function () {
|
||||||
|
check_next_callback.bind(this)();
|
||||||
|
}).bind(this));
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
console.error('Failed to re-encrypt file. It seems to be corrupt.', _file);
|
||||||
|
check_next_callback.bind(this)();
|
||||||
|
}
|
||||||
|
}).bind(this));
|
||||||
|
/* jshint ignore:end */
|
||||||
|
};
|
||||||
|
setTimeout(files_workload.bind(this), 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
var promise_custom_field_files_update = function () {
|
||||||
|
if (this.parent.plain_credential.custom_fields.length === 0) {
|
||||||
|
this.call_progress(new progress_datatype(0, 0, 'custom_field_files'));
|
||||||
|
this.call_then("No custom field files to update");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.total = this.parent.plain_credential.custom_fields.length;
|
||||||
|
console.log("total custom_field_files_update = " + this.total);
|
||||||
|
this.current = 0;
|
||||||
|
|
||||||
|
const custom_field_workload = function () {
|
||||||
|
const check_next_callback = function () {
|
||||||
|
this.current++;
|
||||||
|
this.call_progress(new progress_datatype(this.current, this.total, 'custom_field_files'));
|
||||||
|
|
||||||
|
if (this.current === this.total) {
|
||||||
|
this.call_then('All custom field files has been updated');
|
||||||
|
} else {
|
||||||
|
setTimeout(custom_field_workload.bind(this), 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.parent.plain_credential.custom_fields[this.current].field_type !== 'file') {
|
||||||
|
check_next_callback.bind(this)();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const _file = this.parent.plain_credential.custom_fields[this.current].value;
|
||||||
|
/* jshint ignore:start */
|
||||||
|
FileService.getFile(_file).then((function (fileData) {
|
||||||
|
try {
|
||||||
|
//Decrypt with old key
|
||||||
|
fileData.filename = EncryptService.decryptString(fileData.filename, this.parent.old_password);
|
||||||
|
fileData.file_data = EncryptService.decryptString(fileData.file_data, this.parent.old_password);
|
||||||
|
|
||||||
|
FileService.updateFile(fileData, this.parent.new_password).then((function () {
|
||||||
|
check_next_callback.bind(this)();
|
||||||
|
}).bind(this));
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
console.error('Failed to re-encrypt custom field file. It seems to be corrupt.', _file);
|
||||||
|
check_next_callback.bind(this)();
|
||||||
|
}
|
||||||
|
}).bind(this));
|
||||||
|
/* jshint ignore:end */
|
||||||
|
};
|
||||||
|
setTimeout(custom_field_workload.bind(this), 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
var promise_revisions_update = function () {
|
var promise_revisions_update = function () {
|
||||||
|
|
@ -287,12 +360,13 @@
|
||||||
this.call_then("No history to update");
|
this.call_then("No history to update");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var _revision = revisions[this.current];
|
|
||||||
//Decrypt!
|
|
||||||
_revision.credential_data = service.decryptCredential(_revision.credential_data, this.parent.old_password);
|
|
||||||
_revision.credential_data = service.encryptCredential(_revision.credential_data, this.parent.new_password);
|
|
||||||
this.current++;
|
|
||||||
|
|
||||||
|
var _revision = revisions[this.current];
|
||||||
|
|
||||||
|
const decrypted_revision_credential_data = service.decryptCredential(_revision.credential_data, this.parent.old_password);
|
||||||
|
_revision.credential_data = service.encryptCredential(decrypted_revision_credential_data, this.parent.new_password);
|
||||||
|
|
||||||
|
this.current++;
|
||||||
this.call_progress(new progress_datatype(this.current + this.upload, this.total, 'revisions'));
|
this.call_progress(new progress_datatype(this.current + this.upload, this.total, 'revisions'));
|
||||||
|
|
||||||
service.updateRevision(_revision).then((function () {
|
service.updateRevision(_revision).then((function () {
|
||||||
|
|
@ -344,6 +418,18 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
master_promise.promises++;
|
||||||
|
/** global: C_Promise */
|
||||||
|
(new C_Promise(promise_custom_field_files_update, new password_data())).progress(function (data) {
|
||||||
|
master_promise.call_progress(data);
|
||||||
|
}).then(function () {
|
||||||
|
console.warn("End custom field files update");
|
||||||
|
master_promise.promises--;
|
||||||
|
if (master_promise.promises === 0) {
|
||||||
|
master_promise.call_then(master_promise.credential_data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
master_promise.promises++;
|
master_promise.promises++;
|
||||||
/** global: C_Promise */
|
/** global: C_Promise */
|
||||||
(new C_Promise(promise_revisions_update, new password_data())).progress(function (data) {
|
(new C_Promise(promise_revisions_update, new password_data())).progress(function (data) {
|
||||||
|
|
|
||||||
|
|
@ -160,13 +160,27 @@
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
downloadSharedFile: function (credential, file) {
|
downloadSharedFile: function (credential, file) {
|
||||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/credential/' + credential.guid + '/file/' + file.guid);
|
const queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/credential/' + credential.guid + '/file/' + file.guid);
|
||||||
return $http.get(queryUrl).then(function (response) {
|
return $http.get(queryUrl).then(function (response) {
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
return response.data;
|
return response.data;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
uploadSharedFile: function (credential, file, key) {
|
||||||
|
const queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/credential/' + credential.guid + '/file');
|
||||||
|
let _file = angular.copy(file);
|
||||||
|
_file.filename = EncryptService.encryptString(_file.filename, key);
|
||||||
|
const data = EncryptService.encryptString(angular.copy(file.data), key);
|
||||||
|
_file.data = data;
|
||||||
|
return $http.post(queryUrl, _file).then(function (response) {
|
||||||
|
if (response.data) {
|
||||||
|
return response.data;
|
||||||
|
} else {
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
encryptSharedCredential: function (credential, sharedKey) {
|
encryptSharedCredential: function (credential, sharedKey) {
|
||||||
var _credential = angular.copy(credential);
|
var _credential = angular.copy(credential);
|
||||||
_credential.shared_key = EncryptService.encryptString(sharedKey);
|
_credential.shared_key = EncryptService.encryptString(sharedKey);
|
||||||
|
|
|
||||||
|
|
@ -122,6 +122,30 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
reEncryptACLSharingKeys: function (vault, oldVaultPass, newVaultPass, EncryptService) {
|
||||||
|
const queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/vault/' + vault.guid + '/acl');
|
||||||
|
return $http.get(queryUrl).then(function (response) {
|
||||||
|
if (response.data) {
|
||||||
|
const updateACLSharingKey = function (index) {
|
||||||
|
let acl = response.data[index];
|
||||||
|
const decrypted_shared_key = EncryptService.decryptString(angular.copy(acl.shared_key), oldVaultPass);
|
||||||
|
acl.shared_key = EncryptService.encryptString(decrypted_shared_key, newVaultPass);
|
||||||
|
|
||||||
|
const patchUrl = OC.generateUrl('apps/passman/api/v2/sharing/credential/' + acl.item_guid + '/acl/shared_key');
|
||||||
|
$http.patch(patchUrl, {
|
||||||
|
shared_key: acl.shared_key
|
||||||
|
}).then(function () {
|
||||||
|
if (index < response.data.length - 1) {
|
||||||
|
return updateACLSharingKey(index + 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
if (response.data[0]) {
|
||||||
|
return updateACLSharingKey(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
deleteVault: function (vault, file_ids) {
|
deleteVault: function (vault, file_ids) {
|
||||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/vaults/' + vault.guid);
|
var queryUrl = OC.generateUrl('apps/passman/api/v2/vaults/' + vault.guid);
|
||||||
var deleteFilesUrl = OC.generateUrl('apps/passman/api/v2/files/delete');
|
var deleteFilesUrl = OC.generateUrl('apps/passman/api/v2/files/delete');
|
||||||
|
|
|
||||||
|
|
@ -273,6 +273,17 @@ class ShareService {
|
||||||
return $this->sharingACL->getCredentialAclList($item_guid);
|
return $this->sharingACL->getCredentialAclList($item_guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the access control list by vault guid
|
||||||
|
*
|
||||||
|
* @param string $user_id
|
||||||
|
* @param string $vault_guid
|
||||||
|
* @return Entity[]
|
||||||
|
*/
|
||||||
|
public function getVaultAclList(string $user_id, string $vault_guid) {
|
||||||
|
return $this->sharingACL->getVaultEntries($user_id, $vault_guid);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $item_guid
|
* @param string $item_guid
|
||||||
* @return Entity[]
|
* @return Entity[]
|
||||||
|
|
|
||||||
|
|
@ -55,12 +55,13 @@ class Admin implements ISettings {
|
||||||
* @return TemplateResponse
|
* @return TemplateResponse
|
||||||
*/
|
*/
|
||||||
public function getForm(): TemplateResponse {
|
public function getForm(): TemplateResponse {
|
||||||
|
$hasInternetConnection = $this->config->getSystemValue('has_internet_connection', true);
|
||||||
$checkVersion = $this->config->getAppValue('passman', 'check_version', '1') === '1';
|
$checkVersion = $this->config->getAppValue('passman', 'check_version', '1') === '1';
|
||||||
$localVersion = $this->appManager->getAppInfo('passman')["version"];
|
$localVersion = $this->appManager->getAppInfo('passman')["version"];
|
||||||
$githubVersion = $this->l->t('Unable to get version info');
|
$githubVersion = $this->l->t('Unable to get version info');
|
||||||
$githubReleaseUrl = null;
|
$githubReleaseUrl = null;
|
||||||
|
|
||||||
if ($checkVersion) {
|
if ($checkVersion && $hasInternetConnection) {
|
||||||
// get latest GitHub release version
|
// get latest GitHub release version
|
||||||
|
|
||||||
$url = 'https://api.github.com/repos/nextcloud/passman/releases/latest';
|
$url = 'https://api.github.com/repos/nextcloud/passman/releases/latest';
|
||||||
|
|
@ -90,6 +91,7 @@ class Admin implements ISettings {
|
||||||
'githubVersion' => $githubVersion,
|
'githubVersion' => $githubVersion,
|
||||||
'githubReleaseUrl' => $githubReleaseUrl,
|
'githubReleaseUrl' => $githubReleaseUrl,
|
||||||
'checkVersion' => $checkVersion,
|
'checkVersion' => $checkVersion,
|
||||||
|
'hasInternetConnection' => $hasInternetConnection,
|
||||||
], 'blank');
|
], 'blank');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue