diff options
author | brantje <brantje@gmail.com> | 2017-02-20 02:01:01 +0300 |
---|---|---|
committer | brantje <brantje@gmail.com> | 2017-02-22 20:02:55 +0300 |
commit | fd8dcc6c1ca9e2a5effdff71ee37999d61a58b41 (patch) | |
tree | 2e2aacaff8de8f246da6cf1606fd4e8c3b9fcbb1 | |
parent | 514cb569fba1ee7333f49d8adc4b7be6b52497b4 (diff) |
Add feature to request vault destructions
29 files changed, 667 insertions, 43 deletions
diff --git a/Gruntfile.js b/Gruntfile.js index 06ca2eb8..50f5a3c8 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -29,6 +29,7 @@ module.exports = function (grunt) { }, jshint: { options: { + reporter: require('jshint-stylish'), curly: false, eqeqeq: true, eqnull: true, diff --git a/appinfo/database.xml b/appinfo/database.xml index 5df22b47..2770c002 100644 --- a/appinfo/database.xml +++ b/appinfo/database.xml @@ -548,4 +548,44 @@ </field> </declaration> </table> + <table> + <name>*dbprefix*passman_delete_vault_request</name> + <declaration> + <field> + <name>id</name> + <type>integer</type> + <notnull>true</notnull> + <autoincrement>true</autoincrement> + <unsigned>true</unsigned> + <primary>true</primary> + <length>8</length> + </field> + <field> + <name>vault_guid</name> + <type>text</type> + <notnull>true</notnull> + <length>64</length> + </field> + <field> + <name>reason</name> + <type>text</type> + <notnull>true</notnull> + <length>64</length> + </field> + <field> + <name>requested_by</name> + <type>text</type> + <notnull>false</notnull> + <length>64</length> + </field> + <field> + <name>created</name> + <type>integer</type> + <length>64</length> + <default>0</default> + <notnull>false</notnull> + <unsigned>true</unsigned> + </field> + </declaration> + </table> </database>
\ No newline at end of file diff --git a/appinfo/info.xml b/appinfo/info.xml index 88c5dc04..d5538e06 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -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.1.0</version> + <version>2.1.1</version> <author homepage="https://github.com/brantje">Sander Brand</author> <author homepage="https://github.com/animalillo">Marcos Zuriaga</author> <namespace>Passman</namespace> diff --git a/appinfo/routes.php b/appinfo/routes.php index 2886d210..d06f5fce 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -88,5 +88,9 @@ return [ //Admin routes ['name' => 'admin#searchUser', 'url' => '/admin/search', 'verb' => 'GET'], ['name' => 'admin#moveCredentials', 'url' => '/admin/move', 'verb' => 'POST'], + ['name' => 'admin#requestDeletion', 'url' => '/admin/request-deletion/{vault_guid}', 'verb' => 'POST'], + ['name' => 'admin#deleteRequestDeletion', 'url' => '/admin/request-deletion/{vault_guid}', 'verb' => 'DELETE'], + ['name' => 'admin#listRequests', 'url' => '/admin/delete-requests', 'verb' => 'GET'], + ['name' => 'admin#acceptRequestDeletion', 'url' => '/admin/accept-delete-request', 'verb' => 'POST'], ] ];
\ No newline at end of file diff --git a/controller/admincontroller.php b/controller/admincontroller.php index 4830f040..7e9328ca 100644 --- a/controller/admincontroller.php +++ b/controller/admincontroller.php @@ -12,15 +12,19 @@ namespace OCA\Passman\Controller; use OCA\Passman\Db\CredentialRevision; +use OCA\Passman\Db\DeleteVaultRequest; use OCA\Passman\Service\CredentialRevisionService; +use OCA\Passman\Service\DeleteVaultRequestService; use OCA\Passman\Service\FileService; use OCA\Passman\Service\VaultService; +use OCA\Passman\Utility\Utils; use OCP\IConfig; use OCP\IRequest; use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\ApiController; use OCA\Passman\Service\CredentialService; use \OCP\App; +use OCP\JSON; class AdminController extends ApiController { private $userId; @@ -28,6 +32,7 @@ class AdminController extends ApiController { private $credentialService; private $fileService; private $revisionService; + private $deleteVaultRequestService; private $config; public function __construct($AppName, @@ -37,6 +42,7 @@ class AdminController extends ApiController { CredentialService $credentialService, FileService $fileService, CredentialRevisionService $revisionService, + DeleteVaultRequestService $deleteVaultRequestService, IConfig $config ) { parent::__construct( @@ -50,30 +56,32 @@ class AdminController extends ApiController { $this->credentialService = $credentialService; $this->fileService = $fileService; $this->revisionService = $revisionService; + $this->deleteVaultRequestService = $deleteVaultRequestService; + $this->config = $config; } - public function searchUser($term){ + public function searchUser($term) { $um = \OC::$server->getUserManager(); $results = array(); $searchResult = $um->search($term); - foreach ($searchResult as $user){ + foreach ($searchResult as $user) { array_push($results, array( "value" => $user->getUID(), - "label" => $user->getDisplayName() . ' ('. $user->getBackendClassName() .')', + "label" => $user->getDisplayName() . ' (' . $user->getBackendClassName() . ')', )); } return new JSONResponse($results); } - public function moveCredentials($source_account, $destination_account){ + public function moveCredentials($source_account, $destination_account) { $vaults = $this->vaultService->getByUser($source_account); foreach ($vaults as $vault) { $credentials = $this->credentialService->getCredentialsByVaultId($vault->getId(), $source_account); - foreach($credentials as $credential){ + foreach ($credentials as $credential) { $revisions = $this->revisionService->getRevisions($credential->getId()); - foreach ($revisions as $revision){ + foreach ($revisions as $revision) { $r = new CredentialRevision(); $r->setId($revision['revision_id']); $r->setGuid($revision['guid']); @@ -94,10 +102,87 @@ class AdminController extends ApiController { } $files = $this->fileService->getFilesFromUser($source_account); - foreach($files as $file){ + foreach ($files as $file) { $file->setUserId($destination_account); $this->fileService->updateFile($file); } - return new JSONResponse(array('success'=> true)); + return new JSONResponse(array('success' => true)); + } + + public function listRequests(){ + $requests = $this->deleteVaultRequestService->getDeleteRequests(); + $results = array(); + foreach($requests as $request){ + $r = $request->jsonSerialize(); + $r['displayName'] = Utils::getNameByUid($request->getRequestedBy()); + array_push($results, $r); + } + return new JSONResponse($results); + } + + public function acceptRequestDeletion($vault_guid, $requested_by){ + $req = $this->deleteVaultRequestService->getDeleteRequestForVault($vault_guid); + try{ + $vault = $this->vaultService->getByGuid($vault_guid, $requested_by); + } catch (\Exception $e){ + //Ignore + } + + if(isset($vault)){ + $credentials = $this->credentialService->getCredentialsByVaultId($vault->getId(), $requested_by); + + foreach($credentials as $credential){ + $revisions = $this->revisionService->getRevisions($credential->getId()); + foreach($revisions as $revision){ + $this->revisionService->deleteRevision($revision['revision_id'], $requested_by); + } + $this->credentialService->deleteCredential($credential); + } + $this->vaultService->deleteVault($vault_guid, $requested_by); + } + $this->deleteVaultRequestService->removeDeleteRequestForVault($req); + + return new JSONResponse(array('result' => true)); + } + + /** + * @NoAdminRequired + */ + public function requestDeletion($vault_guid, $reason) { + $req = $this->deleteVaultRequestService->getDeleteRequestForVault($vault_guid); + if($req){ + return new JSONResponse('Already exists'); + } + $vault = $this->vaultService->getByGuid($vault_guid, $this->userId); + $result = false; + if ($vault) { + $delete_request = new DeleteVaultRequest(); + $delete_request->setRequestedBy($this->userId); + $delete_request->setVaultGuid($vault->getGuid()); + $delete_request->setReason($reason); + $delete_request->setCreated(time()); + $result = $this->deleteVaultRequestService->createRequest($delete_request); + + } + return new JSONResponse(array('result' => $result)); + } + + /** + * @NoAdminRequired + */ + public function deleteRequestDeletion($vault_guid) { + $delete_request = false; + $result = false; + try { + $delete_request = $this->deleteVaultRequestService->getDeleteRequestForVault($vault_guid); + } catch (\Exception $exception){ + // Ignore it + } + + if ($delete_request) { + $this->deleteVaultRequestService->removeDeleteRequestForVault($delete_request); + $result = true; + } + return new JSONResponse(array('result' => $result)); } }
\ No newline at end of file diff --git a/controller/translationcontroller.php b/controller/translationcontroller.php index 5f24e211..ecd862de 100644 --- a/controller/translationcontroller.php +++ b/controller/translationcontroller.php @@ -347,6 +347,8 @@ class TranslationController extends ApiController { // templates/views/vaults.html 'last.access' => $this->trans->t('Last accessed'), 'never' => $this->trans->t('Never'), + + 'no.vaults' => $this->trans->t('No vaults found, why not create one?'), 'min.vault.key.strength' => $this->trans->t('Password strength must be at least: {{strength}}'), @@ -362,6 +364,20 @@ class TranslationController extends ApiController { 'auto.logout' => $this->trans->t('Logout of this vault automatically after: '), 'vault.decrypt' => $this->trans->t('Decrypt vault'), + 'req.intro1' => $this->trans->t('Seems you lost the vault password and you\'re unable to login.'), + 'req.intro2' => $this->trans->t('If you want this vault removed you can request removal of the vault here.'), + 'req.intro3' => $this->trans->t('An admin then accept to the request (or not)'), + + 'request.deletion.warning' => $this->trans->t('After an admin destroy\'s this vault, all credentials will be lost'), + 'request.deletion.reason' => $this->trans->t('Reason to request deletion (optional):'), + 'request.deletion' => $this->trans->t('Request vault destruction'), + 'request.deletion.accept' => $this->trans->t('Yes, request an admin to destroy this vault'), + 'cancel.request.deletion' => $this->trans->t('Cancel destruction request'), + 'deletion.requested' => $this->trans->t('Vault destruction requested'), + 'deletion.removed' => $this->trans->t('Request removed'), + 'delete.request.pending' => $this->trans->t('Destruction request pending'), + + // templates/bookmarklet.php 'http.warning' => $this->trans->t('Warning! Adding credentials over http can be insecure!'), 'bm.active.vault' => $this->trans->t('Logged in to {{vault_name}}'), diff --git a/controller/vaultcontroller.php b/controller/vaultcontroller.php index 44cf89da..357608eb 100644 --- a/controller/vaultcontroller.php +++ b/controller/vaultcontroller.php @@ -11,6 +11,7 @@ namespace OCA\Passman\Controller; +use OCA\Passman\Service\DeleteVaultRequestService; use OCA\Passman\Service\EncryptService; use OCA\Passman\Service\SettingsService; use OCA\Passman\Utility\NotFoundJSONResponse; @@ -27,12 +28,14 @@ class VaultController extends ApiController { private $vaultService; private $credentialService; private $settings; + private $deleteVaultRequestService; public function __construct($AppName, IRequest $request, $UserId, VaultService $vaultService, CredentialService $credentialService, + DeleteVaultRequestService $deleteVaultRequestService, SettingsService $settings) { parent::__construct( $AppName, @@ -43,6 +46,7 @@ class VaultController extends ApiController { $this->userId = $UserId; $this->vaultService = $vaultService; $this->credentialService = $credentialService; + $this->deleteVaultRequestService = $deleteVaultRequestService; $this->settings = $settings; } @@ -68,6 +72,7 @@ class VaultController extends ApiController { 'public_sharing_key' => $vault->getPublicSharingKey(), 'last_access' => $vault->getlastAccess(), 'challenge_password' => $credential->{$secret_field}(), + 'delete_request_pending' => ($this->deleteVaultRequestService->getDeleteRequestForVault($vault->getGuid())) ? true : false )); } } @@ -109,7 +114,8 @@ class VaultController extends ApiController { 'public_sharing_key' => $vault->getPublicSharingKey(), 'sharing_keys_generated' => $vault->getSharingKeysGenerated(), 'vault_settings' => $vault->getVaultSettings(), - 'last_access' => $vault->getlastAccess() + 'last_access' => $vault->getlastAccess(), + 'delete_request_pending' => ($this->deleteVaultRequestService->getDeleteRequestForVault($vault->getGuid())) ? true : false ); $result['credentials'] = $credentials; diff --git a/css/admin.css b/css/admin.css index 8bcecfbb..e732ee21 100644 --- a/css/admin.css +++ b/css/admin.css @@ -2,5 +2,12 @@ padding: 5px; } #passwordSharingSettings #mover input[type="text"] { width: 350px; } +#passwordSharingSettings #requests-table { + width: 100%; } +#passwordSharingSettings .link { + color: #0066ff !important; + cursor: pointer; } +#passwordSharingSettings .link:hover { + text-decoration: underline; } /*# sourceMappingURL=admin.css.map */ diff --git a/css/admin.css.map b/css/admin.css.map index da775fe5..f71ec9fd 100644 --- a/css/admin.css.map +++ b/css/admin.css.map @@ -1,6 +1,6 @@ { "version": 3, -"mappings": "AAGM,wCAAE;EACA,OAAO,EAAE,GAAG;AAGhB,kDAAkB;EAChB,KAAK,EAAE,KAAK", +"mappings": "AAGM,wCAAE;EACA,OAAO,EAAE,GAAG;AAGhB,kDAAkB;EAChB,KAAK,EAAE,KAAK;AAGhB,wCAAe;EACb,KAAK,EAAE,IAAI;AAIb,8BAAK;EACH,KAAK,EAAE,kBAA2B;EAClC,MAAM,EAAE,OAAO;AAEjB,oCAAW;EACT,eAAe,EAAE,SAAS", "sources": ["../sass/admin.scss"], "names": [], "file": "admin.css" diff --git a/css/app.css b/css/app.css index f1dd5817..cddac936 100644 --- a/css/app.css +++ b/css/app.css @@ -326,6 +326,13 @@ display: inline-block; } .vault_wrapper .login_form .button { margin-top: 10px; } + .vault_wrapper .reset_form { + padding: 16px; } + .vault_wrapper .reset_form label { + margin-top: 20px; + display: block; } + .vault_wrapper .reset_form input[type="text"] { + width: 100%; } .vault_wrapper .login_opts { margin-bottom: 10px; } diff --git a/css/app.css.map b/css/app.css.map index ee8782a0..25e62a7d 100644 --- a/css/app.css.map +++ b/css/app.css.map @@ -1,6 +1,6 @@ { "version": 3, -"mappings": "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", +"mappings": "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", "sources": ["../sass/app.scss","../sass/variables.scss","../sass/mixins.scss","../sass/partials/button.scss","../sass/partials/popovermenu.scss","../sass/partials/tabs.scss","../sass/partials/pwgen.scss","../sass/vaults.scss","../sass/credentials.scss","../sass/menu.scss","../sass/share_credential.scss","../sass/settings.scss"], "names": [], "file": "app.css" diff --git a/js/app/app.js b/js/app/app.js index 229ce6e3..d14aa92d 100644 --- a/js/app/app.js +++ b/js/app/app.js @@ -67,13 +67,19 @@ .when('/vault/:vault_id/edit/:credential_id', { templateUrl: 'views/edit_credential.html', controller: 'CredentialEditCtrl' - }).when('/vault/:vault_id/:credential_id/share', { - templateUrl: 'views/share_credential.html', - controller: 'ShareCtrl' - }).when('/vault/:vault_id/:credential_id/revisions', { - templateUrl: 'views/credential_revisions.html', - controller: 'RevisionCtrl' - }) + }) + .when('/vault/:vault_id/:credential_id/share', { + templateUrl: 'views/share_credential.html', + controller: 'ShareCtrl' + }) + .when('/vault/:vault_id/:credential_id/revisions', { + templateUrl: 'views/credential_revisions.html', + controller: 'RevisionCtrl' + }) + .when('/vault/:vault_id/request-deletion', { + templateUrl: 'views/vault_req_deletion.html', + controller: 'RequestDeleteCtrl' + }) .when('/vault/:vault_id/settings', { templateUrl: 'views/settings.html', controller: 'SettingsCtrl' diff --git a/js/app/controllers/generic-csv-importer.js b/js/app/controllers/generic-csv-importer.js index e3cc178c..e87d5b32 100644 --- a/js/app/controllers/generic-csv-importer.js +++ b/js/app/controllers/generic-csv-importer.js @@ -85,37 +85,36 @@ prop: null } ]; - + var tagMapper = function (t) { + return {text: t}; + }; var rowToCredential = function (row) { var _credential = PassmanImporter.newCredential(); for(var k = 0; k < $scope.import_fields.length; k++){ var field = $scope.import_fields[k]; if(field){ if(field === 'otp'){ - _credential.otp.secret = row[k] + _credential.otp.secret = row[k]; } else if(field === 'custom_field'){ var key = ($scope.matched) ? $scope.parsed_csv[0][k] : 'Custom field '+ k; _credential.custom_fields.push({ 'label': key, 'value': row[k], 'secret': 0 - }) + }); } else if(field === 'tags'){ if( row[k]) { console.log(row, k); var tags = row[k].split(','); console.log(); - _credential.tags = tags.map(function (t) { - console.log(t); - return {text: t} - }); + _credential.tags = tags.map(tagMapper); } } else{ _credential[field] = row[k]; } } } - return _credential + return _credential; }; @@ -204,6 +203,6 @@ $scope.updateExample = function () { var start = ($scope.skipFirstRow) ? 1 : 0; $scope.inspectCredential($scope.parsed_csv[start]); - } + }; }]); }());
\ No newline at end of file diff --git a/js/app/controllers/vault.js b/js/app/controllers/vault.js index 235017aa..de14b39a 100644 --- a/js/app/controllers/vault.js +++ b/js/app/controllers/vault.js @@ -151,6 +151,10 @@ }; + $scope.requestDeletion = function (vault) { + $location.path('/vault/' + vault.guid +'/request-deletion'); + }; + var _loginToVault = function (vault, vault_key) { var _vault = angular.copy(vault); _vault.vaultKey = angular.copy(vault_key); diff --git a/js/app/controllers/vaultreqdeletion.js b/js/app/controllers/vaultreqdeletion.js new file mode 100644 index 00000000..be54fafb --- /dev/null +++ b/js/app/controllers/vaultreqdeletion.js @@ -0,0 +1,61 @@ +/** + * 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 function + * @name passmanApp.controller:MainCtrl + * @description + * # MainCtrl + * Controller of the passmanApp + */ + angular.module('passmanApp') + .controller('RequestDeleteCtrl', ['$scope', '$location', '$http', '$routeParams', 'VaultService', 'NotificationService', '$translate', + function ($scope, $location, $http, $routeParams, VaultService, NotificationService, $translate) { + $scope.reason = ''; + VaultService.getVault({guid: $routeParams.vault_id}).then(function(vault){ + $scope.pending_deletion = vault.delete_request_pending; + }); + + $scope.requestDeletion = function () { + var queryUrl = OC.generateUrl('apps/passman/admin/request-deletion/'+ $routeParams.vault_id); + var params = { + reason: $scope.reason + }; + + $http.post(queryUrl, params).then(function (response) { + NotificationService.showNotification($translate.instant('deletion.requested'), 5000); + $location.path('#/'); + }); + }; + + $scope.removeRequestDeletion = function () { + var queryUrl = OC.generateUrl('apps/passman/admin/request-deletion/' + $routeParams.vault_id); + $http.delete(queryUrl).then(function (response) { + NotificationService.showNotification($translate.instant('deletion.removed'), 5000); + $location.path('#/'); + }); + }; + }]); +}());
\ No newline at end of file diff --git a/js/app/directives/credentialtemplate.js b/js/app/directives/credentialtemplate.js index 66f47271..9b03db90 100644 --- a/js/app/directives/credentialtemplate.js +++ b/js/app/directives/credentialtemplate.js @@ -39,7 +39,6 @@ }, link: function (scope, element, attrs) { - console.log(attrs.showLabel) scope.showLabel = (attrs.hasOwnProperty('showLabel')); } }; diff --git a/js/settings-admin.js b/js/settings-admin.js index dcb945e9..186c66d5 100644 --- a/js/settings-admin.js +++ b/js/settings-admin.js @@ -59,7 +59,7 @@ $(document).ready(function () { setAdminKey: function (key, value) { var request = $.ajax({ - url: this._baseUrl + '/' + key + '/' + value +'/admin1/admin2', + url: this._baseUrl + '/' + key + '/' + value + '/admin1/admin2', method: 'POST' }); request.done(function () { @@ -72,7 +72,7 @@ $(document).ready(function () { }); }, getKey: function (key) { - if(this._settings.hasOwnProperty(key)){ + if (this._settings.hasOwnProperty(key)) { return this._settings[key]; } return false; @@ -124,7 +124,7 @@ $(document).ready(function () { settings.setAdminKey('vault_key_strength', $(this).val()); }); - if($('form[name="passman_settings"]').length === 2){ + if ($('form[name="passman_settings"]').length === 2) { $('form[name="passman_settings"]')[1].remove(); } @@ -132,10 +132,10 @@ $(document).ready(function () { 'source_account': '', 'destination_account': '' }; - $( ".username-autocomplete" ).autocomplete({ + $(".username-autocomplete").autocomplete({ source: OC.generateUrl('apps/passman/admin/search'), minLength: 1, - select: function( event, ui ) { + select: function (event, ui) { accountMover[$(this).attr('id')] = ui.item.value; } }); @@ -144,10 +144,10 @@ $(document).ready(function () { var self = this; $('#moveStatus').hide(); $(self).attr('disabled', 'disabled'); - $(self).html('<i class="fa fa-spinner fa-spin"></i> Moving...'); - if(accountMover.source_account && accountMover.destination_account){ + $(self).html('<i class="fa fa-spinner fa-spin"></i> ' + OC.L10N.translate('passman', 'Moving') + '...'); + if (accountMover.source_account && accountMover.destination_account) { $.post(OC.generateUrl('apps/passman/admin/move'), accountMover, function (data) { - if(data.success){ + if (data.success) { $(self).removeAttr('disabled'); $(self).html('Move'); $('#moveStatus').fadeIn(); @@ -159,5 +159,74 @@ $(document).ready(function () { } }); + function format_date(date) { + date = new Date(date); + var month=date.getMonth(); + var year=date.getFullYear(); + var day=date.getDate(); + var hour=date.getHours(); + var minutes=date.getMinutes(); + var seconds=date.getSeconds(); + + month=month+1; //javascript date goes from 0 to 11 + if (month<10){ + month="0"+month; //adding the prefix + } + if (hour<10){ + hour="0"+hour; //adding the prefix + } + if (minutes<10){ + minutes="0"+minutes; //adding the prefix + } + if (seconds<10){ + seconds="0"+seconds; //adding the prefix + } + + + + return day+"-"+month+"-"+year+" "+hour+":"+minutes+":"+seconds; + } + + function acceptDeleteRequest (el, req) { + if (!confirm(OC.L10N.translate('passman', "Are you really sure?\nThis will delete the vault and all credentials in it!"))) { + return; + } + $.post(OC.generateUrl('apps/passman/admin/accept-delete-request'), req, function (result) { + console.log(result); + $(el).parent().parent().remove(); + }) + } + + function ignoreDeleteRequest (el, req) { + $.ajax({ + url: OC.generateUrl('apps/passman/admin/request-deletion/' + req.vault_guid), + type: 'DELETE', + success: function (result) { + $(el).parent().parent().remove(); + } + }); + } + + $.get(OC.generateUrl('apps/passman/admin/delete-requests'), function (requests) { + var table = $('#requests-table tbody'); + $.each(requests, function (k, request) { + var accept = $('<span class="link">[Accept] </span>'); + accept.click(function () { + var _self = this; + acceptDeleteRequest(_self, request); + }); + + var ignore = $('<span class="link">[Ignore]</span>'); + ignore.click(function () { + var _self = this; + ignoreDeleteRequest(_self, request); + }); + + var cols = $('<td>' + request.id + '</td><td>' + request.displayName + '</td><td>' + request.reason + '</td><td>' + format_date(request.created * 1000 )+ '</td>'); + var actions = $('<td></td>').append(accept).append(ignore); + table.append($('<tr></tr>').append(cols).append(actions)); + }) + }); + $('#passman-tabs').tabs(); }); diff --git a/js/templates.js b/js/templates.js index 55388a81..9c91811e 100644 --- a/js/templates.js +++ b/js/templates.js @@ -1,4 +1,4 @@ -angular.module('templates-main', ['views/credential_revisions.html', 'views/edit_credential.html', 'views/partials/credential_template.html', 'views/partials/forms/edit_credential/basics.html', 'views/partials/forms/edit_credential/custom_fields.html', 'views/partials/forms/edit_credential/files.html', 'views/partials/forms/edit_credential/otp.html', 'views/partials/forms/edit_credential/password.html', 'views/partials/forms/settings/export.html', 'views/partials/forms/settings/general_settings.html', 'views/partials/forms/settings/generic_csv_import.html', 'views/partials/forms/settings/import.html', 'views/partials/forms/settings/password_settings.html', 'views/partials/forms/settings/sharing.html', 'views/partials/forms/settings/tool.html', 'views/partials/forms/share_credential/basics.html', 'views/partials/forms/share_credential/link_sharing.html', 'views/partials/password-meter.html', 'views/settings.html', 'views/share_credential.html', 'views/show_vault.html', 'views/vaults.html']); +angular.module('templates-main', ['views/credential_revisions.html', 'views/edit_credential.html', 'views/partials/credential_template.html', 'views/partials/forms/edit_credential/basics.html', 'views/partials/forms/edit_credential/custom_fields.html', 'views/partials/forms/edit_credential/files.html', 'views/partials/forms/edit_credential/otp.html', 'views/partials/forms/edit_credential/password.html', 'views/partials/forms/settings/export.html', 'views/partials/forms/settings/general_settings.html', 'views/partials/forms/settings/generic_csv_import.html', 'views/partials/forms/settings/import.html', 'views/partials/forms/settings/password_settings.html', 'views/partials/forms/settings/sharing.html', 'views/partials/forms/settings/tool.html', 'views/partials/forms/share_credential/basics.html', 'views/partials/forms/share_credential/link_sharing.html', 'views/partials/password-meter.html', 'views/settings.html', 'views/share_credential.html', 'views/show_vault.html', 'views/vault_req_deletion.html', 'views/vaults.html']); angular.module('views/credential_revisions.html', []).run(['$templateCache', function ($templateCache) { 'use strict'; @@ -129,8 +129,14 @@ angular.module('views/show_vault.html', []).run(['$templateCache', function ($te ' (settings.user_sharing_enabled === 1 || settings.user_sharing_enabled === \'1\' || settings.link_sharing_enabled === 1 || settings.link_sharing_enabled === \'1\')"><span class="fa fa-share"></span> {{ \'share\' | translate}}</button> <button class="button" ng-click="getRevisions(selectedCredential)" ng-if="selectedCredential.delete_time == 0 && hasPermission(selectedCredential.acl.permissions, permissions.permissions.HISTORY)"><span class="fa fa-undo"></span> {{ \'revisions\' | translate}}</button> <button class="button" ng-if="selectedCredential.delete_time > 0" ng-click="recoverCredential(selectedCredential) && hasPermission(selectedCredential.acl.permissions, permissions.permissions.WRITE)"><span class="fa fa-recycle"></span> {{\'recover\' | translate}}</button> <button class="button" ng-if="selectedCredential.delete_time > 0" ng-click="destroyCredential(selectedCredential)"><span class="fa fa-bomb"></span> {{\'destroy\' | translate}}</button></div></div></div></div><div class="share_popup" style="display: none">{{ \'sharereq.title\' | translate}}<br>{{ \'sharereq.line1\' | translate}}<br>{{ \'sharereq.line2\' | translate}} {{active_vault.vault_id}}<table class="table"><thead><tr><td>{{ \'label\' | translate}}</td><td>{{ \'permissions\' | translate}}</td><td>{{ \'received.from\' | translate}}</td><td>{{ \'date\' | translate}}</td></tr></thead><tr ng-repeat="share_request in incoming_share_requests" ng-if="share_request.target_vault_id == active_vault.vault_id"><td>{{share_request.credential_label}}</td><td>{{share_request.permissions}}</td><td>{{share_request.from_user_id}}</td><td>{{share_request.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</td><td><span class="link" ng-click="acceptShareRequest(share_request)">{{ \'accept\' | translate}}</span> | <span class="link" ng-click="declineShareRequest(share_request)">{{ \'decline\' | translate}}</span></td></tr></table></div>'); }]); +angular.module('views/vault_req_deletion.html', []).run(['$templateCache', function ($templateCache) { + 'use strict'; + $templateCache.put('views/vault_req_deletion.html', + '<div class="vault_wrapper"><div class="reset_form" ng-show="!pending_deletion">{{ \'req.intro1\' | translate }}<br>{{ \'req.intro2\' | translate }}<br>{{ \'req.intro3\' | translate }}<br><br><b>{{ \'request.deletion.warning\' | translate}}</b><label>{{ \'request.deletion.reason\' | translate }}</label><input type="text" ng-model="reason" class="form-control"> <button class="button button-red" ng-click="requestDeletion()">{{ \'request.deletion.accept\' | translate }}</button> <a class="pull-right button button-geen" ng-href="#/">{{ \'cancel\' | translate}}</a></div><div class="reset_form" ng-show="pending_deletion"><button class="button button-red" ng-click="removeRequestDeletion()">Cancel destruction request</button> <a class="pull-right button button-geen" ng-href="#/">Cancel</a></div></div>'); +}]); + angular.module('views/vaults.html', []).run(['$templateCache', function ($templateCache) { 'use strict'; $templateCache.put('views/vaults.html', - '<div class="vault_wrapper"><div class="vaults" ng-if="!list_selected_vault && !creating_vault"><div class="ui-select-container ui-select-bootstrap vaultlist"><ul><li ng-click="newVault()">+ Create a new vault</li><li ng-repeat="vault in vaults" ng-class="{\'selected\': vault == list_selected_vault }" ng-click="selectVault(vault)"><div><span class="ui-select-choices-row-inner"><div class="ng-binding ng-scope">{{vault.name}}</div><small class="ng-binding ng-scope">{{ \'created\' | translate}}: {{vault.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}} | {{ \'last.access\' | translate}}: <span ng-if="vault.last_access > 0">{{vault.last_access * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</span> <span ng-if="vault.last_access === 0">{{\'never\' | translate}}</span></small></span></div></li><li ng-if="vaults.length === 0">{{ \'no.vaults\' | translate}}</li></ul></div></div><div ng-if="creating_vault"><div class="login_form" ng-init="vault_name = \'\'; vault_key=\'\'; ">{{\'new.vault.name\' | translate}}<div><input type="text" ng-model="vault_name" required></div><div>{{ \'new.vault.pass\' | translate}} <input type="password" ng-model="vault_key" required><ng-password-meter password="vault_key" score="vault_key_score"></ng-password-meter></div><div>{{ \'new.vault.passr\' | translate}} <input type="password" ng-model="vault_key2" required></div><div ng-show="error || vault_key_score.score < minimal_value_key_strength" class="error"><ul><li ng-show="error">{{error}}</li><li ng-show="vault_key_score.score < minimal_value_key_strength">{{\'min.vault.key.strength\' | translate:required_score}}</li></ul></div><div><small>{{\'new.vault.sharing_key_notice\' | translate}}</small></div><div class="button_wrapper"><button class="button button-geen" ng-if="!creating_keys" ng-click="createVault(vault_name, vault_key, vault_key2)" ng-disabled="vault_key_score.score < minimal_value_key_strength || vault_key !== vault_key2 || vault_key === \'\'">{{ \'new.vault.create\' | translate }}</button><div class="button" ng-if="creating_keys"><span><i class="fa fa-spinner fa-spin"></i> {{creating_keys}}</span></div><div class="button button-red" ng-click="clearState()">{{ \'cancel\' | translate}}</div><div class="hidden">{{sharing_keys}}</div></div></div></div><div ng-if="list_selected_vault != false"><div class="vaultlist"><ul><li ng-click="clearState()">{{ \'go.back.vaults\' | translate }}</li></ul></div><div class="login_form"><div ng-show="error" class="error"><ul><li>{{error}}</li></ul></div>{{ \'input.vault.password\' | translate}} {{list_selected_vault.name}}<div class="pw-input"><input type="password" ng-model="vault_key" ng-enter="loginToVault(list_selected_vault, vault_key)"> <small class="last_access">{{\'last.access\' | translate}}: <span ng-if="list_selected_vault.last_access > 0">{{list_selected_vault.last_access * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</span> <span ng-if="list_selected_vault.last_access === 0">Never</span></small></div><div class="login_opts"><div><label><input type="checkbox" ng-checked="default_vault" ng-click="toggleDefaultVault()"> {{ \'vault.default\' | translate}}</label></div><div><label><input type="checkbox" ng-checked="remember_vault_password" ng-click="toggleRememberPassword()"> {{ \'vault.auto.login\' | translate}}</label></div><div><label><input type="checkbox" ng-checked="auto_logout_timer" ng-click="toggleAutoLogout()"> {{ \'auto.logout\' | translate}}</label><select ng-model="logout_timer" ng-change="selectLogoutTimer(logout_timer)"><option value="0">Never</option><option value="30">30 minutes</option><option value="60">60 minutes</option><option value="90">90 minutes</option><option value="180">3 hour</option><option value="480">8 hour</option></select></div></div><div class="alert alert-danger" ng-show="vault_tries[list_selected_vault.guid].timeout !== 0" translate="vault.locked" translate-value-tries="{{ vault_tries[list_selected_vault.guid].tries }}" translate-value-time="{{ vault_tries[list_selected_vault.guid].timeout | toHHMMSS }}"></div><button class="button button-geen" ng-click="loginToVault(list_selected_vault, vault_key)" ng-disabled="vault_tries[list_selected_vault.guid].timeout !== 0">{{ \'vault.decrypt\' | translate}}</button></div></div></div>'); + '<div class="vault_wrapper"><div class="vaults" ng-if="!list_selected_vault && !creating_vault"><div class="ui-select-container ui-select-bootstrap vaultlist"><ul><li ng-click="newVault()">+ Create a new vault</li><li ng-repeat="vault in vaults" ng-class="{\'selected\': vault == list_selected_vault }" ng-click="selectVault(vault)"><div><span class="ui-select-choices-row-inner"><div class="ng-binding ng-scope">{{vault.name}} <span class="pull-right" style="color: #ce3702" ng-show="vault.delete_request_pending">{{ \'delete.request.pending\' | translate}}</span></div><small class="ng-binding ng-scope">{{ \'created\' | translate}}: {{vault.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}} | {{ \'last.access\' | translate}}: <span ng-if="vault.last_access > 0">{{vault.last_access * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</span> <span ng-if="vault.last_access === 0">{{\'never\' | translate}}</span></small></span></div></li><li ng-if="vaults.length === 0">{{ \'no.vaults\' | translate}}</li></ul></div></div><div ng-if="creating_vault"><div class="login_form" ng-init="vault_name = \'\'; vault_key=\'\'; ">{{\'new.vault.name\' | translate}}<div><input type="text" ng-model="vault_name" required></div><div>{{ \'new.vault.pass\' | translate}} <input type="password" ng-model="vault_key" required><ng-password-meter password="vault_key" score="vault_key_score"></ng-password-meter></div><div>{{ \'new.vault.passr\' | translate}} <input type="password" ng-model="vault_key2" required></div><div ng-show="error || vault_key_score.score < minimal_value_key_strength" class="error"><ul><li ng-show="error">{{error}}</li><li ng-show="vault_key_score.score < minimal_value_key_strength">{{\'min.vault.key.strength\' | translate:required_score}}</li></ul></div><div><small>{{\'new.vault.sharing_key_notice\' | translate}}</small></div><div class="button_wrapper"><button class="button button-geen" ng-if="!creating_keys" ng-click="createVault(vault_name, vault_key, vault_key2)" ng-disabled="vault_key_score.score < minimal_value_key_strength || vault_key !== vault_key2 || vault_key === \'\'">{{ \'new.vault.create\' | translate }}</button><div class="button" ng-if="creating_keys"><span><i class="fa fa-spinner fa-spin"></i> {{creating_keys}}</span></div><div class="button button-red" ng-click="clearState()">{{ \'cancel\' | translate}}</div><div class="hidden">{{sharing_keys}}</div></div></div></div><div ng-if="list_selected_vault != false"><div class="vaultlist"><ul><li ng-click="clearState()">{{ \'go.back.vaults\' | translate }}</li></ul></div><div class="login_form"><div ng-show="error" class="error"><ul><li>{{error}}</li></ul></div>{{ \'input.vault.password\' | translate}} {{list_selected_vault.name}}<div class="pw-input"><input type="password" ng-model="vault_key" ng-enter="loginToVault(list_selected_vault, vault_key)"> <small class="last_access">{{\'last.access\' | translate}}: <span ng-if="list_selected_vault.last_access > 0">{{list_selected_vault.last_access * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</span> <span ng-if="list_selected_vault.last_access === 0">Never</span></small></div><div class="login_opts"><div><label><input type="checkbox" ng-checked="default_vault" ng-click="toggleDefaultVault()"> {{ \'vault.default\' | translate}}</label></div><div><label><input type="checkbox" ng-checked="remember_vault_password" ng-click="toggleRememberPassword()"> {{ \'vault.auto.login\' | translate}}</label></div><div><label><input type="checkbox" ng-checked="auto_logout_timer" ng-click="toggleAutoLogout()"> {{ \'auto.logout\' | translate}}</label><select ng-model="logout_timer" ng-change="selectLogoutTimer(logout_timer)"><option value="0">Never</option><option value="30">30 minutes</option><option value="60">60 minutes</option><option value="90">90 minutes</option><option value="180">3 hour</option><option value="480">8 hour</option></select></div></div><div class="alert alert-danger" ng-show="vault_tries[list_selected_vault.guid].timeout !== 0" translate="vault.locked" translate-value-tries="{{ vault_tries[list_selected_vault.guid].tries }}" translate-value-time="{{ vault_tries[list_selected_vault.guid].timeout | toHHMMSS }}"></div><button class="button button-geen" ng-click="loginToVault(list_selected_vault, vault_key)" ng-disabled="vault_tries[list_selected_vault.guid].timeout !== 0">{{ \'vault.decrypt\' | translate}}</button> <span ng-click="forgottenPassword = true;" style="margin-top: 10px; padding: 6px 12px" class="link pull-right" ng-show="!forgottenPassword">Forgot password?</span> <button ng-show="forgottenPassword" class="pull-right button button-red" ng-click="requestDeletion(list_selected_vault)"><span ng-show="list_selected_vault.delete_request_pending">{{ \'cancel.request.deletion\' | translate }}</span> <span ng-show="!list_selected_vault.delete_request_pending">{{ \'request.deletion\' | translate }}</span></button></div></div></div>'); }]); diff --git a/lib/Db/DeleteVaultRequest.php b/lib/Db/DeleteVaultRequest.php new file mode 100644 index 00000000..dd9eb897 --- /dev/null +++ b/lib/Db/DeleteVaultRequest.php @@ -0,0 +1,67 @@ +<?php +/** + * 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/>. + * + */ + +namespace OCA\Passman\Db; +use \OCP\AppFramework\Db\Entity; + +/** + * @method integer getId() + * @method void setId(integer $value) + * @method void setVaultGuid(string $value) + * @method string getVaultGuid() + * @method void setReason(string $value) + * @method string getReason() + * @method void setRequestedBy(string $value) + * @method string getRequestedBy() + * @method void setCreated(integer $value) + * @method integer getCreated() + */ + + +class DeleteVaultRequest extends Entity implements \JsonSerializable{ + + use EntityJSONSerializer; + + protected $vaultGuid; + protected $reason; + protected $requestedBy; + protected $created; + + public function __construct() { + // add types in constructor + $this->addType('id', 'integer'); + $this->addType('created', 'integer'); + } + /** + * Turns entity attributes into an array + */ + public function jsonSerialize() { + return [ + 'id' => $this->getId(), + 'vault_guid' => $this->getVaultGuid(), + 'reason' => $this->getReason(), + 'requested_by' => $this->getRequestedBy(), + 'created' => $this->getCreated(), + ]; + } +}
\ No newline at end of file diff --git a/lib/Db/DeleteVaultRequestMapper.php b/lib/Db/DeleteVaultRequestMapper.php new file mode 100644 index 00000000..19dc8562 --- /dev/null +++ b/lib/Db/DeleteVaultRequestMapper.php @@ -0,0 +1,77 @@ +<?php +/** + * 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/>. + * + */ + +namespace OCA\Passman\Db; + + +use Icewind\SMB\Share; +use OCA\Passman\Utility\Utils; +use OCP\AppFramework\Db\DoesNotExistException; +use OCP\AppFramework\Db\Mapper; +use OCP\IDBConnection; + +class DeleteVaultRequestMapper extends Mapper { + const TABLE_NAME = 'passman_delete_vault_request'; + + public function __construct(IDBConnection $db) { + parent::__construct($db, self::TABLE_NAME); + } + + /** + * Create a new enty in the db + * @param DeleteVaultRequest $request + * @return \OCP\AppFramework\Db\Entity + */ + public function createRequest(DeleteVaultRequest $request){ + return $this->insert($request); + } + + /** + * Get all delete requests + * @return \OCP\AppFramework\Db\Entity + */ + public function getDeleteRequests(){ + $q = "SELECT * FROM *PREFIX*" . self::TABLE_NAME; + return $this->findEntities($q); + } + + /** + * Get request for an vault id + * @param $vault_id integer The vault id + * @return \OCP\AppFramework\Db\Entity + */ + public function getDeleteRequestsForVault($vault_guid){ + $q = "SELECT * FROM *PREFIX*" . self::TABLE_NAME .' WHERE `vault_guid` = ?'; + return $this->findEntity($q, [$vault_guid]); + } + + /** + * Deletes the given delete request + * @param DeleteVaultRequest $shareRequest Request to delete + * @return DeleteVaultRequest The deleted request + */ + public function removeDeleteVaultRequest(DeleteVaultRequest $request){ + return $this->delete($request); + } + +}
\ No newline at end of file diff --git a/lib/Service/DeleteVaultRequestService.php b/lib/Service/DeleteVaultRequestService.php new file mode 100644 index 00000000..82820722 --- /dev/null +++ b/lib/Service/DeleteVaultRequestService.php @@ -0,0 +1,85 @@ +<?php +/** + * 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/>. + * + */ + +namespace OCA\Passman\Service; + +use OCA\Passman\Db\DeleteVaultRequest; +use OCA\Passman\Db\DeleteVaultRequestMapper; + +use OCP\AppFramework\Db\DoesNotExistException; + + +class DeleteVaultRequestService { + + private $deleteVaultRequestMapper; + + public function __construct(DeleteVaultRequestMapper $deleteVaultRequestMapper) { + $this->deleteVaultRequestMapper = $deleteVaultRequestMapper; + } + + /** + * Create a new DeleteVaultRequest + * + * @param $request DeleteVaultRequest + * @return \OCA\Passman\Db\DeleteVaultRequest + */ + public function createRequest(DeleteVaultRequest $request) { + return $this->deleteVaultRequestMapper->insert($request); + } + + /** + * Create a new DeleteVaultRequest + * + * @return \OCA\Passman\Db\DeleteVaultRequest[] + */ + public function getDeleteRequests() { + return $this->deleteVaultRequestMapper->getDeleteRequests(); + } + + /** + * Create a new DeleteVaultRequest + * + * @param $vault_id integer The vault id + * @return bool | DeleteVaultRequest + */ + public function getDeleteRequestForVault($vault_guid) { + try { + $result = $this->deleteVaultRequestMapper->getDeleteRequestsForVault($vault_guid); + return $result; + } catch (\Exception $e) { + return false; + } + } + + /** + * Create a new DeleteVaultRequest + * + * @param $req DeleteVaultRequest + * @return bool | DeleteVaultRequest + */ + public function removeDeleteRequestForVault(DeleteVaultRequest $req) { + $this->deleteVaultRequestMapper->removeDeleteVaultRequest($req); + } + + +}
\ No newline at end of file diff --git a/lib/Utility/Utils.php b/lib/Utility/Utils.php index 79087364..011bd7dd 100644 --- a/lib/Utility/Utils.php +++ b/lib/Utility/Utils.php @@ -50,4 +50,14 @@ class Utils { return sprintf('%04X%04X-%04X-%04X-%04X-%04X%04X%04X', mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(16384, 20479), mt_rand(32768, 49151), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535)); } + + /** + * @param $uid + * @return string + */ + public static function getNameByUid($uid){ + $um = \OC::$server->getUserManager(); + $u = $um->get($uid); + return $u->getDisplayName(); + } }
\ No newline at end of file diff --git a/package.json b/package.json index 08c7d973..d6d1e7a9 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "grunt-replace": "^1.0.1", "html-minifier": "^3.0.2", "jasmine-core": "^2.5.2", + "jshint-stylish": "^2.2.1", "karma": "^1.3.0", "karma-chrome-launcher": "^2.0.0", "karma-firefox-launcher": "^1.0.0", diff --git a/sass/admin.scss b/sass/admin.scss index 259ad564..8bac6f46 100644 --- a/sass/admin.scss +++ b/sass/admin.scss @@ -9,4 +9,16 @@ width: 350px; } } + #requests-table{ + width: 100%; + } + + + .link{ + color: rgb(0, 102, 255) !important; + cursor: pointer; + } + .link:hover{ + text-decoration: underline; + } }
\ No newline at end of file diff --git a/sass/vaults.scss b/sass/vaults.scss index 07c64ade..2af23141 100644 --- a/sass/vaults.scss +++ b/sass/vaults.scss @@ -90,8 +90,20 @@ margin-top: 10px; } } + .reset_form { + padding: 16px; + label{ + margin-top: 20px; + display: block; + } + input[type="text"]{ + width: 100%; + + } + } .login_opts{ margin-bottom: 10px; + } } diff --git a/templates/main.php b/templates/main.php index 412a54d1..033d5bea 100644 --- a/templates/main.php +++ b/templates/main.php @@ -46,6 +46,7 @@ script('passman', 'app/controllers/settings'); script('passman', 'app/controllers/import'); script('passman', 'app/controllers/export'); script('passman', 'app/controllers/generic-csv-importer'); +script('passman', 'app/controllers/vaultreqdeletion'); script('passman', 'app/filters/range'); script('passman', 'app/filters/propsfilter'); script('passman', 'app/filters/byte'); diff --git a/templates/part.admin.php b/templates/part.admin.php index 9673d540..945441fb 100644 --- a/templates/part.admin.php +++ b/templates/part.admin.php @@ -11,10 +11,10 @@ style('passman', 'vendor/font-awesome/font-awesome.min'); $checkVersion = OC::$server->getConfig()->getAppValue('passman', 'check_version', '1') === '1'; $AppInstance = new App(); $localVersion = $AppInstance->getAppInfo("passman")["version"]; +$githubVersion = $l->t('Unable to get version info'); if ($checkVersion) { // get latest master version $version = false; - $githubVersion = $l->t('Unable to get version info'); $url = 'https://raw.githubusercontent.com/nextcloud/passman/master/appinfo/info.xml'; try { @@ -68,7 +68,7 @@ $ciphers = openssl_get_cipher_methods(); <a href="#mover"><?php p($l->t('Credential mover')); ?></a> </li> <li> - <a href="#tabs-3"><?php p($l->t('Vault delete requests')); ?></a> + <a href="#tabs-3"><?php p($l->t('Vault destruction requests')); ?></a> </li> </ul> <div id="general"> @@ -162,7 +162,21 @@ $ciphers = openssl_get_cipher_methods(); </div> <div id="tabs-3"> - Requests to delete vault + <?php p($l->t('Requests to destroy vault')); ?> + <table id="requests-table"> + <thead> + <tr> + <th><?php p($l->t('Request ID')); ?></th> + <th><?php p($l->t('Requested by')); ?></th> + <th><?php p($l->t('Reason')); ?></th> + <th><?php p($l->t('Created')); ?></th> + <th></th> + </tr> + </thead> + <tbody> + + </tbody> + </table> </div> </div> diff --git a/templates/views/vault_req_deletion.html b/templates/views/vault_req_deletion.html new file mode 100644 index 00000000..40fdeda9 --- /dev/null +++ b/templates/views/vault_req_deletion.html @@ -0,0 +1,30 @@ +<div class="vault_wrapper"> + <div class="reset_form" ng-show="!pending_deletion"> + {{ 'req.intro1' | translate }}<br/> + {{ 'req.intro2' | translate }}<br/> + {{ 'req.intro3' | translate }}<br/> + <br/> + + <b>{{ 'request.deletion.warning' | translate}}</b> + + <label>{{ 'request.deletion.reason' | translate }}</label> + <input type="text" ng-model="reason" class="form-control"> + <button class="button button-red" + ng-click="requestDeletion()"> + {{ 'request.deletion.accept' | translate }} + </button> + <a class="pull-right button button-geen" ng-href="#/"> + {{ 'cancel' | translate}} + </a> + </div> + + <div class="reset_form" ng-show="pending_deletion"> + <button class="button button-red" + ng-click="removeRequestDeletion()"> + Cancel destruction request + </button> + <a class="pull-right button button-geen" ng-href="#/"> + Cancel + </a> + </div> +</div>
\ No newline at end of file diff --git a/templates/views/vaults.html b/templates/views/vaults.html index 6fb12e40..b4a82c5a 100644 --- a/templates/views/vaults.html +++ b/templates/views/vaults.html @@ -9,7 +9,7 @@ ng-click="selectVault(vault)"> <div> <span class="ui-select-choices-row-inner"> - <div class="ng-binding ng-scope">{{vault.name}}</div> + <div class="ng-binding ng-scope">{{vault.name}} <span class="pull-right" style="color: #ce3702;" ng-show="vault.delete_request_pending">{{ 'delete.request.pending' | translate}}</span></div> <small class="ng-binding ng-scope"> {{ 'created' | translate}}: {{vault.created * 1000 | date:'dd-MM-yyyy @ HH:mm:ss'}} @@ -134,6 +134,11 @@ ng-click="loginToVault(list_selected_vault, vault_key)" ng-disabled="vault_tries[list_selected_vault.guid].timeout !== 0"> {{ 'vault.decrypt' | translate}} </button> + <span ng-click="forgottenPassword = true;" style="margin-top: 10px; padding: 6px 12px;" class="link pull-right" ng-show="!forgottenPassword">Forgot password?</span> + <button ng-show="forgottenPassword" class="pull-right button button-red" ng-click="requestDeletion(list_selected_vault)"> + <span ng-show="list_selected_vault.delete_request_pending">{{ 'cancel.request.deletion' | translate }}</span> + <span ng-show="!list_selected_vault.delete_request_pending">{{ 'request.deletion' | translate }}</span> + </button> </div> </div> |