diff --git a/controller/credentialcontroller.php b/controller/credentialcontroller.php index 99e68f13..6acd2011 100644 --- a/controller/credentialcontroller.php +++ b/controller/credentialcontroller.php @@ -262,6 +262,12 @@ class CredentialController extends ApiController { */ public function updateRevision($credential_id, $revision_id, $credential_data){ $revision = null; + try { + $credential = $this->credentialService->getCredentialById($credential_id, $this->userId); + } catch (DoesNotExistException $e) { + return new NotFoundResponse(); + } + try{ $revision = $this->credentialRevisionService->getRevision($revision_id); } catch(DoesNotExistException $exception){ @@ -269,6 +275,8 @@ class CredentialController extends ApiController { } $revision->setCredentialData($credential_data); + $this->credentialRevisionService->updateRevision($revision); + return new JSONResponse(array()); } } \ No newline at end of file diff --git a/controller/sharecontroller.php b/controller/sharecontroller.php index b5123109..5a2da468 100644 --- a/controller/sharecontroller.php +++ b/controller/sharecontroller.php @@ -419,12 +419,14 @@ class ShareController extends ApiController { * @param $credential_guid * @param $file_guid * @NoAdminRequired + * @return JSONResponse + * @return NotFoundResponse */ public function getFile($item_guid, $file_guid){ try { $credential = $this->credentialService->getCredentialByGUID($item_guid); } catch (DoesNotExistException $e){ - return new JSONResponse(array()); + return new NotFoundResponse(); } $acl = $this->shareService->getACL($this->userId->getUID(), $credential->getGuid()); diff --git a/js/app/controllers/public_shared_credential.js b/js/app/controllers/public_shared_credential.js index 089eec1e..4e078bd0 100644 --- a/js/app/controllers/public_shared_credential.js +++ b/js/app/controllers/public_shared_credential.js @@ -8,7 +8,7 @@ angular.module('passmanApp') .controller('PublicSharedCredential', ['$scope', 'ShareService','$window', function ($scope, ShareService, $window) { $scope.test = 'hello world'; - //@TODO Add download files + //@TODO Add download files $scope.loading = false; $scope.loadSharedCredential = function () { $scope.loading = true; diff --git a/js/app/controllers/revision.js b/js/app/controllers/revision.js index 5551d0fc..1033f7f5 100644 --- a/js/app/controllers/revision.js +++ b/js/app/controllers/revision.js @@ -8,8 +8,8 @@ * Controller of the passmanApp */ angular.module('passmanApp') - .controller('RevisionCtrl', ['$scope', 'SettingsService', 'VaultService', 'CredentialService', '$location', '$routeParams', '$rootScope', 'NotificationService', '$filter', - function ($scope, SettingsService, VaultService, CredentialService, $location, $routeParams, $rootScope, NotificationService, $filter) { + .controller('RevisionCtrl', ['$scope', 'SettingsService', 'VaultService', 'CredentialService', '$location', '$routeParams', '$rootScope', 'NotificationService', '$filter', 'ShareService','EncryptService', + function ($scope, SettingsService, VaultService, CredentialService, $location, $routeParams, $rootScope, NotificationService, $filter, ShareService, EncryptService) { if (!SettingsService.getSetting('defaultVault') || !SettingsService.getSetting('defaultVaultPass')) { if (!$scope.active_vault) { @@ -52,8 +52,24 @@ angular.module('passmanApp') } $scope.selectRevision = function (revision) { + console.log(revision, $scope.storedCredential); + var key; + + return; $scope.selectedRevision = angular.copy(revision); - $scope.selectedRevision.credential_data = CredentialService.decryptCredential(angular.copy(revision.credential_data)); + + if(!$scope.storedCredential.hasOwnProperty('acl') && $scope.storedCredential.hasOwnProperty('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){ + $scope.selectedRevision.credential_data = CredentialService.decryptCredential(angular.copy(revision.credential_data)); + } else { + $scope.selectedRevision.credential_data = ShareService.decryptSharedCredential(angular.copy(revision.credential_data), key); + } + $rootScope.$emit('app_menu', true); }; diff --git a/js/app/controllers/share.js b/js/app/controllers/share.js index cd59d303..17d6e47b 100644 --- a/js/app/controllers/share.js +++ b/js/app/controllers/share.js @@ -9,7 +9,7 @@ * This file is part of passman, licensed under AGPLv3 */ angular.module('passmanApp') - .controller('ShareCtrl', ['$scope', 'VaultService', 'CredentialService', 'SettingsService', '$location', '$routeParams', 'ShareService', 'NotificationService', 'SharingACL','EncryptService', 'FileService', + .controller('ShareCtrl', ['$scope', 'VaultService', 'CredentialService', 'SettingsService', '$location', '$routeParams', 'ShareService', 'NotificationService', 'SharingACL', 'EncryptService', 'FileService', function ($scope, VaultService, CredentialService, SettingsService, $location, $routeParams, ShareService, NotificationService, SharingACL, EncryptService, FileService) { $scope.active_vault = VaultService.getActiveVault(); @@ -49,7 +49,7 @@ angular.module('passmanApp') } var storedCredential = SettingsService.getSetting('share_credential'); - if(!storedCredential) { + if (!storedCredential) { $location.path('/vault/' + $routeParams.vault_id); } else { $scope.storedCredential = CredentialService.decryptCredential(angular.copy(storedCredential)); @@ -94,7 +94,7 @@ angular.module('passmanApp') } }; - var getAcl = function() { + var getAcl = function () { ShareService.getSharedCredentialACL($scope.storedCredential).then(function (aclList) { var _list = [] var enc_key = ($scope.storedCredential.shared_key) ? EncryptService.decryptString(angular.copy($scope.storedCredential.shared_key)) : false; @@ -138,7 +138,7 @@ angular.module('passmanApp') $scope.$watch('share_settings.upload_progress.done', function () { console.log(); - if($scope.share_settings.upload_progress.done == $scope.share_settings.upload_progress.total){ + if ($scope.share_settings.upload_progress.done == $scope.share_settings.upload_progress.total) { getAcl() } }); @@ -150,11 +150,11 @@ angular.module('passmanApp') return ShareService.search($query) }; - $scope.hasPermission = function(acl, permission){ + $scope.hasPermission = function (acl, permission) { return acl.hasPermission(permission); }; - $scope.setPermission = function(acl, permission){ + $scope.setPermission = function (acl, permission) { acl.togglePermission(permission); }; $scope.shareWith = function (shareWith, selectedAccessLevel) { @@ -185,8 +185,8 @@ angular.module('passmanApp') NotificationService.showNotification('Credential unshared', 4000) }); - for(var f = 0; f < $scope.storedCredential.files.length; f++){ - var _file = $scope.storedCredential.files[f]; + for (var f = 0; f < $scope.storedCredential.files.length; f++) { + var _file = $scope.storedCredential.files[f]; FileService.getFile(_file).then(function (fileData) { //Decrypt with old key fileData.filename = EncryptService.decryptString(fileData.filename); @@ -220,7 +220,7 @@ angular.module('passmanApp') user: data[0].user_id }); user.vaults = result; - if(!user.hasOwnProperty('acl_id')) { + if (!user.hasOwnProperty('acl_id')) { $scope.uploadChanges(user); } $scope.$digest(); @@ -238,11 +238,11 @@ angular.module('passmanApp') $scope.share_settings.upload_progress.done = 0; $scope.share_settings.upload_progress.total = 0; //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) { console.log('Shared key found'); var enc_key = EncryptService.decryptString(angular.copy($scope.storedCredential.shared_key)); - if($scope.share_settings.linkSharing.enabled){ - var expire_time = new Date(angular.copy( $scope.share_settings.linkSharing.settings.expire_time)).getTime()/1000; + if ($scope.share_settings.linkSharing.enabled) { + var expire_time = new Date(angular.copy($scope.share_settings.linkSharing.settings.expire_time)).getTime() / 1000; var shareObj = { item_id: $scope.storedCredential.credential_id, item_guid: $scope.storedCredential.guid, @@ -251,7 +251,7 @@ angular.module('passmanApp') expire_views: $scope.share_settings.linkSharing.settings.expire_views }; ShareService.createPublicSharedCredential(shareObj).then(function () { - var hash = window.btoa($scope.storedCredential.guid + '<::>'+ enc_key) + var hash = window.btoa($scope.storedCredential.guid + '<::>' + enc_key) $scope.share_link = $location.$$protocol + '://' + $location.$$host + OC.generateUrl('apps/passman/share/public#') + hash; }) } @@ -261,7 +261,7 @@ angular.module('passmanApp') for (var i = 0; i < list.length; i++) { var iterator = i; var target_user = list[i]; - if(target_user.hasOwnProperty('created')){ + if (target_user.hasOwnProperty('created')) { console.log('Updating permissions') var acl = { @@ -279,7 +279,7 @@ angular.module('passmanApp') ShareService.generateSharedKey(20).then(function (key) { var encryptedSharedCredential = ShareService.encryptSharedCredential($scope.storedCredential, key); - CredentialService.updateCredential(encryptedSharedCredential, true).then(function(sharedCredential){ + CredentialService.updateCredential(encryptedSharedCredential, true).then(function (sharedCredential) { $scope.storedCredential = ShareService.decryptSharedCredential(sharedCredential, key); }); @@ -289,8 +289,8 @@ angular.module('passmanApp') // Then decrypt the data obtained with var EncryptService.decryptString(result.file_data); // To update a file you can use the FileService.updateFile - for(var f = 0; f < $scope.storedCredential.files.length; f++){ - var _file = $scope.storedCredential.files[f]; + for (var f = 0; f < $scope.storedCredential.files.length; f++) { + var _file = $scope.storedCredential.files[f]; FileService.getFile(_file).then(function (fileData) { //Decrypt with old key fileData.filename = EncryptService.decryptString(fileData.filename); @@ -299,6 +299,16 @@ angular.module('passmanApp') }) } + CredentialService.getRevisions($scope.storedCredential.credential_id).then(function (revisions) { + console.log(revisions); + for (var r = 0; r < revisions.length; r++) { + var _revision = revisions[r]; + //Decrypt! + _revision.credential_data = CredentialService.decryptCredential(_revision.credential_data); + _revision.credential_data = ShareService.encryptSharedCredential(_revision.credential_data, key); + CredentialService.updateRevision(_revision); + } + }); //@TODO Update revisions with new key (async) // With CredentialService.getRevisions we can get the revisions. @@ -311,8 +321,8 @@ angular.module('passmanApp') } } - if($scope.share_settings.linkSharing.enabled){ - var expire_time = new Date(angular.copy( $scope.share_settings.linkSharing.settings.expire_time)).getTime()/1000; + if ($scope.share_settings.linkSharing.enabled) { + var expire_time = new Date(angular.copy($scope.share_settings.linkSharing.settings.expire_time)).getTime() / 1000; var shareObj = { item_id: $scope.storedCredential.credential_id, item_guid: $scope.storedCredential.guid, @@ -320,8 +330,8 @@ angular.module('passmanApp') expire_timestamp: expire_time, expire_views: $scope.share_settings.linkSharing.settings.expire_views }; - ShareService.createPublicSharedCredential(shareObj).then(function(){ - var hash = window.btoa($scope.storedCredential.guid + '<::>'+ key); + ShareService.createPublicSharedCredential(shareObj).then(function () { + var hash = window.btoa($scope.storedCredential.guid + '<::>' + key); $scope.share_link = $location.$$protocol + '://' + $location.$$host + OC.generateUrl('apps/passman/share/public#') + hash; }); @@ -332,14 +342,14 @@ angular.module('passmanApp') }; $scope.uploadChanges = function (user) { - $scope.share_settings.upload_progress.total ++; + $scope.share_settings.upload_progress.total++; user.accessLevel = angular.copy(user.acl.getAccessLevel()); ShareService.shareWithUser(storedCredential, user) - .then(function(data){ - $scope.share_settings.upload_progress.done ++; - $scope.share_settings.upload_progress.percent = $scope.share_settings.upload_progress.done / $scope.share_settings.upload_progress.total * 100; - }); + .then(function (data) { + $scope.share_settings.upload_progress.done++; + $scope.share_settings.upload_progress.percent = $scope.share_settings.upload_progress.done / $scope.share_settings.upload_progress.total * 100; + }); }; $scope.calculate_total_time = function () { diff --git a/js/app/services/credentialservice.js b/js/app/services/credentialservice.js index 9888aceb..ab4ec482 100644 --- a/js/app/services/credentialservice.js +++ b/js/app/services/credentialservice.js @@ -141,9 +141,9 @@ angular.module('passmanApp') }, updateRevision: function(revision){ var _revision = angular.copy(revision); - _revision.revision_data = window.btoa(_revision.revision_data); - var queryUrl = OC.generateUrl('apps/passman/api/v2/credentials/' + id + '/revision/' + revision.id); - return $http.patch(queryUrl, revision).then(function (response) { + _revision.credential_data = window.btoa(JSON.stringify(_revision.credential_data)); + var queryUrl = OC.generateUrl('apps/passman/api/v2/credentials/' + revision.credential_data.credential_id + '/revision/' + revision.revision_id); + return $http.patch(queryUrl, _revision).then(function (response) { if (response.data) { return response.data; } else { diff --git a/js/templates.js b/js/templates.js index 1eb56672..cecd7b9b 100644 --- a/js/templates.js +++ b/js/templates.js @@ -3,7 +3,7 @@ angular.module('templates-main', ['views/credential_revisions.html', 'views/edit angular.module('views/credential_revisions.html', []).run(['$templateCache', function($templateCache) { 'use strict'; $templateCache.put('views/credential_revisions.html', - '
Revision of {{revision.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}} by {{revision.edited_by}}
No revisions found.
Revision of {{selectedRevision.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}
Label{{selectedRevision.credential_data.label}}
Account
Password
OTP
E-mail
URL
Files
{{field.label}}
Changed{{selectedRevision.credential_data.changed * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}
Created{{selectedRevision.credential_data.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}
'); + '
Revision of {{revision.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}} ({{revision.credential_data.label}}) by {{revision.edited_by}}
No revisions found.
Revision of {{selectedRevision.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}
Label{{selectedRevision.credential_data.label}}
Account
Password
OTP
E-mail
URL
Files
{{field.label}}
Changed{{selectedRevision.credential_data.changed * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}
Created{{selectedRevision.credential_data.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}
'); }]); angular.module('views/edit_credential.html', []).run(['$templateCache', function($templateCache) { diff --git a/lib/Db/CredentialRevision.php b/lib/Db/CredentialRevision.php index 19619eac..edd93309 100644 --- a/lib/Db/CredentialRevision.php +++ b/lib/Db/CredentialRevision.php @@ -55,7 +55,7 @@ class CredentialRevision extends Entity implements \JsonSerializable { 'revision_id' => $this->getId(), 'guid' => $this->getGuid(), 'created' => $this->getCreated(), - 'credential_data' => unserialize(base64_decode($this->getCredentialData())), + 'credential_data' => json_decode(base64_decode($this->getCredentialData())), 'edited_by' => $this->getEditedBy(), ]; } diff --git a/lib/Db/CredentialRevisionMapper.php b/lib/Db/CredentialRevisionMapper.php index cf2177b6..feee9e1c 100644 --- a/lib/Db/CredentialRevisionMapper.php +++ b/lib/Db/CredentialRevisionMapper.php @@ -61,7 +61,7 @@ class CredentialRevisionMapper extends Mapper { $revision->setCreated($this->utils->getTime()); $revision->setCredentialId($credential_id); $revision->setEditedBy($edited_by); - $revision->setCredentialData(base64_encode(serialize($credential))); + $revision->setCredentialData(base64_encode(json_encode($credential))); return $this->insert($revision); } diff --git a/templates/views/credential_revisions.html b/templates/views/credential_revisions.html index 82510bef..ad7e082c 100644 --- a/templates/views/credential_revisions.html +++ b/templates/views/credential_revisions.html @@ -23,7 +23,7 @@ ng-class="{'selected': selectedRevision.revision_id == revision.revision_id}"> - Revision of {{revision.created * 1000 | date:'dd-MM-yyyy @ HH:mm:ss'}} by {{revision.edited_by}} + Revision of {{revision.created * 1000 | date:'dd-MM-yyyy @ HH:mm:ss'}} ({{revision.credential_data.label}}) by {{revision.edited_by}}