From e29753b27c995ad204734bb49a47d9220951cfae Mon Sep 17 00:00:00 2001 From: Julia Radzhabova Date: Tue, 5 Dec 2023 18:25:01 +0300 Subject: [PATCH 1/4] [PDFE] Protect pdf with password (Bug 61126) --- apps/pdfeditor/main/app.js | 6 +- apps/pdfeditor/main/app/controller/Main.js | 6 +- .../main/app/template/FileMenu.template | 2 + apps/pdfeditor/main/app/view/FileMenu.js | 5 + .../pdfeditor/main/app/view/FileMenuPanels.js | 185 ++++++++++++++++++ apps/pdfeditor/main/app_dev.js | 2 + apps/pdfeditor/main/locale/en.json | 13 ++ 7 files changed, 215 insertions(+), 4 deletions(-) diff --git a/apps/pdfeditor/main/app.js b/apps/pdfeditor/main/app.js index b58d01c506..c3ad9a82f8 100644 --- a/apps/pdfeditor/main/app.js +++ b/apps/pdfeditor/main/app.js @@ -156,7 +156,8 @@ require([ 'Common.Controllers.Chat', 'Common.Controllers.Comments', 'Common.Controllers.Draw', - 'Common.Controllers.Plugins' + 'Common.Controllers.Plugins', + 'Common.Controllers.Protection' ] }); @@ -185,7 +186,8 @@ require([ 'common/main/lib/controller/Chat', /** coauthoring end **/ 'common/main/lib/controller/Plugins', - 'common/main/lib/controller/Draw' + 'common/main/lib/controller/Draw', + 'common/main/lib/controller/Protection' ], function() { app.start(); }); diff --git a/apps/pdfeditor/main/app/controller/Main.js b/apps/pdfeditor/main/app/controller/Main.js index 9bfb464d74..8e38d94c2f 100644 --- a/apps/pdfeditor/main/app/controller/Main.js +++ b/apps/pdfeditor/main/app/controller/Main.js @@ -1159,7 +1159,7 @@ define([ this.appOptions.trialMode = params.asc_getLicenseMode(); this.appOptions.isBeta = params.asc_getIsBeta(); this.appOptions.isSignatureSupport= false;//this.appOptions.isEdit && this.appOptions.isDesktopApp && this.appOptions.isOffline && this.api.asc_isSignaturesSupport() && (this.permissions.protect!==false); - this.appOptions.isPasswordSupport = false;//this.appOptions.isEdit && this.api.asc_isProtectionSupport() && (this.permissions.protect!==false); + this.appOptions.isPasswordSupport = this.appOptions.isEdit && this.api.asc_isProtectionSupport() && (this.permissions.protect!==false); this.appOptions.canProtect = (this.permissions.protect!==false); this.appOptions.canHelp = !((typeof (this.editorConfig.customization) == 'object') && this.editorConfig.customization.help===false); @@ -1391,7 +1391,9 @@ define([ if (this.appOptions.isEdit) { // var fontsControllers = application.getController('Common.Controllers.Fonts'); // fontsControllers && fontsControllers.setApi(me.api); - // application.getController('Common.Controllers.Protection').setMode(me.appOptions).setConfig({config: me.editorConfig}, me.api); + + if (me.appOptions.isSignatureSupport || me.appOptions.isPasswordSupport) + application.getController('Common.Controllers.Protection').setMode(me.appOptions).setConfig({config: me.editorConfig}, me.api); var viewport = this.getApplication().getController('Viewport').getView('Viewport'); viewport.applyEditorMode(); diff --git a/apps/pdfeditor/main/app/template/FileMenu.template b/apps/pdfeditor/main/app/template/FileMenu.template index c128df7e8e..6736a39575 100644 --- a/apps/pdfeditor/main/app/template/FileMenu.template +++ b/apps/pdfeditor/main/app/template/FileMenu.template @@ -9,6 +9,7 @@
  • +
  • @@ -31,5 +32,6 @@
    +
    \ No newline at end of file diff --git a/apps/pdfeditor/main/app/view/FileMenu.js b/apps/pdfeditor/main/app/view/FileMenu.js index b553bde17c..440d913337 100644 --- a/apps/pdfeditor/main/app/view/FileMenu.js +++ b/apps/pdfeditor/main/app/view/FileMenu.js @@ -447,6 +447,11 @@ define([ !this.panels['recent'] && (this.panels['recent'] = (new Common.Views.RecentFiles({ el: '#panel-recentfiles', menu:this, recent: this.mode.recent})).render()); } + if (this.mode.isSignatureSupport || this.mode.isPasswordSupport) { + !this.panels['protect'] && (this.panels['protect'] = (new PDFE.Views.FileMenuPanels.ProtectDoc({menu:this})).render()); + this.panels['protect'].setMode(this.mode); + } + if (this.mode.canDownload) { !this.panels['saveas'] && (this.panels['saveas'] = ((new PDFE.Views.FileMenuPanels.ViewSaveAs({menu: this, fileType: this.document.fileType, mode: this.mode})).render())); } else if (this.mode.canDownloadOrigin) diff --git a/apps/pdfeditor/main/app/view/FileMenuPanels.js b/apps/pdfeditor/main/app/view/FileMenuPanels.js index 6f66d19d00..616cb860aa 100644 --- a/apps/pdfeditor/main/app/view/FileMenuPanels.js +++ b/apps/pdfeditor/main/app/view/FileMenuPanels.js @@ -1985,6 +1985,191 @@ define([ } }); + PDFE.Views.FileMenuPanels.ProtectDoc = Common.UI.BaseView.extend(_.extend({ + el: '#panel-protect', + menu: undefined, + + template: _.template([ + '', + '
    ', + '', + '
    ', + '
    <%= scope.txtProtectDocument %>
    ', + '
    ', + '
    ', + '
    ', + '
    <%= scope.txtEncrypted %>
    ', + '
    ', + '
    ', + '
    ', + '
    ', + '
    ', + '
    ', + '
    ', + '', + '
    ', + '
    <%= scope.txtAddSignature %>
    ', + '
    ', + '
    ', + '
    ', + '
    <%= scope.txtAddedSignature %>
    ', + '
    ', + '
    ', + '
    ' + ].join('')), + + initialize: function(options) { + Common.UI.BaseView.prototype.initialize.call(this,arguments); + + this.menu = options.menu; + + var me = this; + this.templateSignature = _.template([ + '
    ', + '
    <%= tipText %>
    ', + '
    ', + '', + '', + '
    ', + '
    ' + ].join('')); + }, + + render: function() { + this.$el.html(this.template({scope: this})); + + var protection = PDFE.getController('Common.Controllers.Protection').getView(); + + this.btnAddPwd = protection.getButton('add-password'); + this.btnAddPwd.render(this.$el.find('#fms-btn-add-pwd')); + this.btnAddPwd.on('click', _.bind(this.closeMenu, this)); + + this.btnChangePwd = protection.getButton('change-password'); + this.btnChangePwd.render(this.$el.find('#fms-btn-change-pwd')); + this.btnChangePwd.on('click', _.bind(this.closeMenu, this)); + + this.btnDeletePwd = protection.getButton('del-password'); + this.btnDeletePwd.render(this.$el.find('#fms-btn-delete-pwd')); + this.btnDeletePwd.on('click', _.bind(this.closeMenu, this)); + + this.cntPassword = $('#id-fms-password'); + this.cntEncryptBlock = this.$el.find('.encrypt-block'); + this.cntEncryptedBlock = this.$el.find('.encrypted-block'); + + this.btnAddInvisibleSign = protection.getButton('signature'); + this.btnAddInvisibleSign.render(this.$el.find('#fms-btn-invisible-sign')); + this.btnAddInvisibleSign.on('click', _.bind(this.closeMenu, this)); + + this.cntSignature = $('#id-fms-signature'); + this.cntSignatureView = $('#id-fms-signature-view'); + + this.cntAddSignature = this.$el.find('.add-signature-block'); + this.cntAddedSignature = this.$el.find('.added-signature-block'); + + if (_.isUndefined(this.scroller)) { + this.scroller = new Common.UI.Scroller({ + el: this.$el, + suppressScrollX: true, + alwaysVisibleY: true + }); + } + + this.$el.on('click', '.signature-edit-link', _.bind(this.onEdit, this)); + this.$el.on('click', '.signature-view-link', _.bind(this.onView, this)); + + return this; + }, + + show: function() { + Common.UI.BaseView.prototype.show.call(this,arguments); + this.updateSignatures(); + this.updateEncrypt(); + this.scroller && this.scroller.update(); + }, + + setMode: function(mode) { + this.mode = mode; + this.cntSignature.toggleClass('hidden', !this.mode.isSignatureSupport); + this.cntPassword.toggleClass('hidden', !this.mode.isPasswordSupport); + }, + + setApi: function(o) { + this.api = o; + return this; + }, + + closeMenu: function() { + this.menu && this.menu.hide(); + }, + + onEdit: function() { + this.menu && this.menu.hide(); + + var me = this; + Common.UI.warning({ + title: this.notcriticalErrorTitle, + msg: this.txtEditWarning, + buttons: ['ok', 'cancel'], + primary: 'ok', + callback: function(btn) { + if (btn == 'ok') { + me.api.asc_RemoveAllSignatures(); + } + } + }); + + }, + + onView: function() { + this.menu && this.menu.hide(); + // PDFE.getController('RightMenu').rightmenu.SetActivePane(Common.Utils.documentSettingsType.Signature, true); + }, + + updateSignatures: function(){ + var valid = this.api.asc_getSignatures(), + hasValid = false, + hasInvalid = false; + + _.each(valid, function(item, index){ + if (item.asc_getValid()==0) + hasValid = true; + else + hasInvalid = true; + }); + + // hasValid = true; + // hasInvalid = true; + + var tipText = (hasInvalid) ? this.txtSignedInvalid : (hasValid ? this.txtSigned : ""); + this.cntSignatureView.html(this.templateSignature({tipText: tipText, hasSigned: (hasValid || hasInvalid)})); + + var isAddedSignature = this.btnAddInvisibleSign.$el.find('button').hasClass('hidden'); + this.cntAddSignature.toggleClass('hidden', isAddedSignature); + this.cntAddedSignature.toggleClass('hidden', !isAddedSignature); + }, + + updateEncrypt: function() { + var isProtected = this.btnAddPwd.$el.find('button').hasClass('hidden'); + this.cntEncryptBlock.toggleClass('hidden', isProtected); + this.cntEncryptedBlock.toggleClass('hidden', !isProtected); + }, + + strProtect: 'Protect Document', + strSignature: 'With Signature', + txtView: 'View signatures', + txtEdit: 'Edit document', + txtSigned: 'Valid signatures has been added to the document. The document is protected from editing.', + txtSignedInvalid: 'Some of the digital signatures in document are invalid or could not be verified. The document is protected from editing.', + notcriticalErrorTitle: 'Warning', + txtEditWarning: 'Editing will remove the signatures from the document.
    Are you sure you want to continue?', + strEncrypt: 'With Password', + txtProtectDocument: 'Encrypt this document with a password', + txtEncrypted: 'A password is required to open this document', + txtAddSignature: 'Ensure the integrity of the document by adding an
    invisible digital signature', + txtAddedSignature: 'Valid signatures have been added to the document.
    The document is protected from editing.' + + }, PDFE.Views.FileMenuPanels.ProtectDoc || {})); + PDFE.Views.PrintWithPreview = Common.UI.BaseView.extend(_.extend({ el: '#panel-print', menu: undefined, diff --git a/apps/pdfeditor/main/app_dev.js b/apps/pdfeditor/main/app_dev.js index 430c77293b..c7abd80ef4 100644 --- a/apps/pdfeditor/main/app_dev.js +++ b/apps/pdfeditor/main/app_dev.js @@ -148,6 +148,7 @@ require([ ,'Common.Controllers.Comments' ,'Common.Controllers.Draw' ,'Common.Controllers.Plugins' + ,'Common.Controllers.Protection' ] }); @@ -176,6 +177,7 @@ require([ ,'common/main/lib/controller/Chat' ,'common/main/lib/controller/Plugins' ,'common/main/lib/controller/Draw' + ,'common/main/lib/controller/Protection' ], function() { window.compareVersions = true; app.start(); diff --git a/apps/pdfeditor/main/locale/en.json b/apps/pdfeditor/main/locale/en.json index ec602fc7fd..e872996d44 100644 --- a/apps/pdfeditor/main/locale/en.json +++ b/apps/pdfeditor/main/locale/en.json @@ -507,6 +507,19 @@ "PDFE.Views.FileMenuPanels.DocumentRights.txtAccessRights": "Access Rights", "PDFE.Views.FileMenuPanels.DocumentRights.txtBtnAccessRights": "Change access rights", "PDFE.Views.FileMenuPanels.DocumentRights.txtRights": "Persons who have rights", + "PDFE.Views.FileMenuPanels.ProtectDoc.strEncrypt": "With password", + "PDFE.Views.FileMenuPanels.ProtectDoc.strProtect": "Protect Document", + "PDFE.Views.FileMenuPanels.ProtectDoc.strSignature": "With signature", + "PDFE.Views.FileMenuPanels.ProtectDoc.txtAddedSignature": "Valid signatures have been added to the document.
    The document is protected from editing.", + "PDFE.Views.FileMenuPanels.ProtectDoc.txtAddSignature": "Ensure the integrity of the document by adding an
    invisible digital signature", + "PDFE.Views.FileMenuPanels.ProtectDoc.txtEdit": "Edit document", + "PDFE.Views.FileMenuPanels.ProtectDoc.txtEditWarning": "Editing will remove signatures from the document.
    Continue?", + "PDFE.Views.FileMenuPanels.ProtectDoc.txtEncrypted": "This document has been protected with password", + "PDFE.Views.FileMenuPanels.ProtectDoc.txtProtectDocument": "Encrypt this document with a password", + "PDFE.Views.FileMenuPanels.ProtectDoc.txtRequestedSignatures": "This document needs to be signed.", + "PDFE.Views.FileMenuPanels.ProtectDoc.txtSigned": "Valid signatures have been added to the document. The document is protected from editing.", + "PDFE.Views.FileMenuPanels.ProtectDoc.txtSignedInvalid": "Some of the digital signatures in the document are invalid or could not be verified. The document is protected from editing.", + "PDFE.Views.FileMenuPanels.ProtectDoc.txtView": "View signatures", "PDFE.Views.FileMenuPanels.Settings.okButtonText": "Apply", "PDFE.Views.FileMenuPanels.Settings.strCoAuthMode": "Co-editing Mode", "PDFE.Views.FileMenuPanels.Settings.strFast": "Fast", From 60036b3b7e82908003f347e17366530cec9985c0 Mon Sep 17 00:00:00 2001 From: Julia Radzhabova Date: Tue, 5 Dec 2023 18:37:49 +0300 Subject: [PATCH 2/4] [PDFE] Add password only for offline files in desktop --- apps/pdfeditor/main/app/controller/Main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/pdfeditor/main/app/controller/Main.js b/apps/pdfeditor/main/app/controller/Main.js index 8e38d94c2f..74ff0746b6 100644 --- a/apps/pdfeditor/main/app/controller/Main.js +++ b/apps/pdfeditor/main/app/controller/Main.js @@ -1159,7 +1159,7 @@ define([ this.appOptions.trialMode = params.asc_getLicenseMode(); this.appOptions.isBeta = params.asc_getIsBeta(); this.appOptions.isSignatureSupport= false;//this.appOptions.isEdit && this.appOptions.isDesktopApp && this.appOptions.isOffline && this.api.asc_isSignaturesSupport() && (this.permissions.protect!==false); - this.appOptions.isPasswordSupport = this.appOptions.isEdit && this.api.asc_isProtectionSupport() && (this.permissions.protect!==false); + this.appOptions.isPasswordSupport = this.appOptions.isEdit && this.appOptions.isDesktopApp && this.appOptions.isOffline && this.api.asc_isProtectionSupport() && (this.permissions.protect!==false); this.appOptions.canProtect = (this.permissions.protect!==false); this.appOptions.canHelp = !((typeof (this.editorConfig.customization) == 'object') && this.editorConfig.customization.help===false); From 0751705307ab26c81a641e615d240e178b8a78c4 Mon Sep 17 00:00:00 2001 From: Julia Radzhabova Date: Wed, 6 Dec 2023 12:31:54 +0300 Subject: [PATCH 3/4] [PDF] Save changes to offline pdf file --- apps/pdfeditor/main/app/controller/LeftMenu.js | 2 +- apps/pdfeditor/main/app/controller/Main.js | 4 ++-- apps/pdfeditor/main/app/controller/Toolbar.js | 8 ++++---- apps/pdfeditor/main/app/view/FileMenuPanels.js | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/pdfeditor/main/app/controller/LeftMenu.js b/apps/pdfeditor/main/app/controller/LeftMenu.js index fc3e7d96ff..f51787e8a6 100644 --- a/apps/pdfeditor/main/app/controller/LeftMenu.js +++ b/apps/pdfeditor/main/app/controller/LeftMenu.js @@ -407,7 +407,7 @@ define([ var value; var fast_coauth = Common.Utils.InternalSettings.get("pdfe-settings-coauthmode"), - canPDFSave = this.mode.isPDFAnnotate || this.mode.isPDFEdit; + canPDFSave = (this.mode.isPDFAnnotate || this.mode.isPDFEdit) && !this.mode.isOffline; /** coauthoring begin **/ if (this.mode.isEdit && !this.mode.isOffline && this.mode.canCoAuthoring && canPDFSave ) { if (this.mode.canChangeCoAuthoring) { diff --git a/apps/pdfeditor/main/app/controller/Main.js b/apps/pdfeditor/main/app/controller/Main.js index 74ff0746b6..0289638192 100644 --- a/apps/pdfeditor/main/app/controller/Main.js +++ b/apps/pdfeditor/main/app/controller/Main.js @@ -1130,9 +1130,9 @@ define([ this.appOptions.isEdit = !isXpsViewer; this.appOptions.canPDFEdit = false;//(this.permissions.edit !== false) && this.appOptions.canLicense; this.appOptions.isPDFEdit = false; // this.appOptions.canPDFEdit && this.editorConfig.mode !== 'view'; !! always open in view mode - this.appOptions.canPDFAnnotate = this.appOptions.canSwitchMode && this.appOptions.canLicense && (this.permissions.comment!== false); + this.appOptions.canPDFAnnotate = (this.appOptions.canSwitchMode || !isXpsViewer && this.appOptions.isDesktopApp && this.appOptions.isOffline) && this.appOptions.canLicense && (this.permissions.comment!== false); this.appOptions.canPDFAnnotate = this.appOptions.canPDFAnnotate && !((typeof (this.editorConfig.customization) == 'object') && this.editorConfig.customization.comments===false); - this.appOptions.isPDFAnnotate = false;// this.appOptions.canLicense && this.appOptions.canPDFAnnotate && !this.appOptions.isPDFEdit && this.editorConfig.mode !== 'view'; !! always open in view mode + this.appOptions.isPDFAnnotate = this.appOptions.canPDFAnnotate && this.appOptions.isDesktopApp && this.appOptions.isOffline; // this.appOptions.canPDFAnnotate && !this.appOptions.isPDFEdit && this.editorConfig.mode !== 'view'; !! online files always open in view mode this.appOptions.canComments = !isXpsViewer; this.appOptions.canViewComments = this.appOptions.canComments; this.appOptions.canChat = this.appOptions.canLicense && !this.appOptions.isOffline && !(this.permissions.chat===false || (this.permissions.chat===undefined) && diff --git a/apps/pdfeditor/main/app/controller/Toolbar.js b/apps/pdfeditor/main/app/controller/Toolbar.js index 4406b8e44c..5be48b77fe 100644 --- a/apps/pdfeditor/main/app/controller/Toolbar.js +++ b/apps/pdfeditor/main/app/controller/Toolbar.js @@ -411,10 +411,10 @@ define([ } }); } else if (this.api) { - var isModified = this.api.asc_isDocumentCanSave(); - var isSyncButton = toolbar.btnCollabChanges && toolbar.btnCollabChanges.cmpEl.hasClass('notify'); - if (!isModified && !isSyncButton && !toolbar.mode.forcesave) - return; + // var isModified = this.api.asc_isDocumentCanSave(); + // var isSyncButton = toolbar.btnCollabChanges && toolbar.btnCollabChanges.cmpEl.hasClass('notify'); + // if (!isModified && !isSyncButton && !toolbar.mode.forcesave) + // return; this.api.asc_Save(); toolbar.btnSave.setDisabled(!toolbar.mode.forcesave && !toolbar.mode.saveAlwaysEnabled); diff --git a/apps/pdfeditor/main/app/view/FileMenuPanels.js b/apps/pdfeditor/main/app/view/FileMenuPanels.js index 616cb860aa..d406b5b2eb 100644 --- a/apps/pdfeditor/main/app/view/FileMenuPanels.js +++ b/apps/pdfeditor/main/app/view/FileMenuPanels.js @@ -659,7 +659,7 @@ define([ this.mode = mode; var fast_coauth = Common.Utils.InternalSettings.get("pdfe-settings-coauthmode"), - canPDFSave = mode.isPDFAnnotate || mode.isPDFEdit; + canPDFSave = (mode.isPDFAnnotate || mode.isPDFEdit) && !mode.isOffline; $('tr.edit', this.el)[mode.isEdit?'show':'hide'](); $('tr.autosave', this.el)[mode.isEdit && canPDFSave && (mode.canChangeCoAuthoring || !fast_coauth) ? 'show' : 'hide'](); From 447858660989ea3335ef1ab770ad5f6482a00bad Mon Sep 17 00:00:00 2001 From: Julia Radzhabova Date: Thu, 21 Dec 2023 23:23:05 +0300 Subject: [PATCH 4/4] Fix for pdf form --- apps/pdfeditor/main/app/controller/Main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/pdfeditor/main/app/controller/Main.js b/apps/pdfeditor/main/app/controller/Main.js index 3808045d75..20d4bf501e 100644 --- a/apps/pdfeditor/main/app/controller/Main.js +++ b/apps/pdfeditor/main/app/controller/Main.js @@ -1196,7 +1196,7 @@ define([ this.appOptions.isEdit = !this.appOptions.isXpsViewer && !this.appOptions.isForm; this.appOptions.canPDFEdit = false;//(this.permissions.edit !== false) && this.appOptions.canLicense; this.appOptions.isPDFEdit = false; // this.appOptions.canPDFEdit && this.editorConfig.mode !== 'view'; !! always open in view mode - this.appOptions.canPDFAnnotate = (this.appOptions.canSwitchMode || !this.appOptions.isXpsViewer && this.appOptions.isDesktopApp && this.appOptions.isOffline) && this.appOptions.canLicense && (this.permissions.comment!== false); + this.appOptions.canPDFAnnotate = (this.appOptions.canSwitchMode || !this.appOptions.isXpsViewer && !this.appOptions.isForm && this.appOptions.isDesktopApp && this.appOptions.isOffline) && this.appOptions.canLicense && (this.permissions.comment!== false); this.appOptions.canPDFAnnotate = this.appOptions.canPDFAnnotate && !((typeof (this.editorConfig.customization) == 'object') && this.editorConfig.customization.comments===false); this.appOptions.isPDFAnnotate = this.appOptions.canPDFAnnotate && this.appOptions.isDesktopApp && this.appOptions.isOffline; // this.appOptions.canPDFAnnotate && !this.appOptions.isPDFEdit && this.editorConfig.mode !== 'view'; !! online files always open in view mode this.appOptions.canComments = !this.appOptions.isXpsViewer && !this.appOptions.isForm;