Add a new pdfjs.enablePermissions
preference, off by default, to allow the PDF documents to disable copying in the viewer (bug 792816)
*Please note:* Most of the necessary API work was done in PR 10033, and the only remaining thing to do here was to implement it in the viewer. The new preference should thus allow e.g. enterprise users to disable copying in the viewer, for PDF documents whose permissions specify that. In order to simplify things the "copy"-permission was implemented using CSS, as suggested in https://bugzilla.mozilla.org/show_bug.cgi?id=792816#c55, which should hopefully suffice.[1] The advantage of this approach, as opposed to e.g. disabling the `textLayer` completely, is first of all that it ensures that searching still works correctly even in copy-protected documents. Secondly this also greatly simplifies the overall implementation, since it doesn't require a lot of code for something that's disabled by default. --- [1] As the discussion in the bug shows, this kind of copy-protection is not very strong and is also generally easy to remove/circumvent in various ways. Hence a simple solution, targeting "regular"-users rather than "power"-users is hopefully deemed acceptable here.
This commit is contained in:
parent
4fe92605b7
commit
8521f70157
@ -151,6 +151,10 @@
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"enablePermissions": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"historyUpdateUrl": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
|
34
web/app.js
34
web/app.js
@ -48,6 +48,7 @@ import {
|
||||
MissingPDFException,
|
||||
OPS,
|
||||
PDFWorker,
|
||||
PermissionFlag,
|
||||
shadow,
|
||||
UnexpectedResponseException,
|
||||
UNSUPPORTED_FEATURES,
|
||||
@ -77,6 +78,7 @@ const DEFAULT_SCALE_DELTA = 1.1;
|
||||
const DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT = 5000; // ms
|
||||
const FORCE_PAGES_LOADED_TIMEOUT = 10000; // ms
|
||||
const WHEEL_ZOOM_DISABLED_TIMEOUT = 1000; // ms
|
||||
const ENABLE_PERMISSIONS_CLASS = "enablePermissions";
|
||||
|
||||
const ViewOnLoad = {
|
||||
UNKNOWN: -1,
|
||||
@ -679,6 +681,7 @@ const PDFViewerApplication = {
|
||||
this.pdfLinkService.setDocument(null);
|
||||
this.pdfDocumentProperties.setDocument(null);
|
||||
}
|
||||
webViewerResetPermissions();
|
||||
this.store = null;
|
||||
this.isInitialViewSet = false;
|
||||
this.downloadComplete = false;
|
||||
@ -1149,6 +1152,10 @@ const PDFViewerApplication = {
|
||||
pdfViewer.focus();
|
||||
}
|
||||
|
||||
// Currently only the "copy"-permission is supported, hence we delay
|
||||
// the `getPermissions` API call until *after* rendering has started.
|
||||
this._initializePermissions(pdfDocument);
|
||||
|
||||
// For documents with different page sizes, once all pages are
|
||||
// resolved, ensure that the correct location becomes visible on load.
|
||||
// (To reduce the risk, in very large and/or slow loading documents,
|
||||
@ -1467,6 +1474,24 @@ const PDFViewerApplication = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
async _initializePermissions(pdfDocument) {
|
||||
const permissions = await pdfDocument.getPermissions();
|
||||
|
||||
if (pdfDocument !== this.pdfDocument) {
|
||||
return; // The document was closed while the permissions resolved.
|
||||
}
|
||||
if (!permissions || !AppOptions.get("enablePermissions")) {
|
||||
return;
|
||||
}
|
||||
// Currently only the "copy"-permission is supported.
|
||||
if (!permissions.includes(PermissionFlag.COPY)) {
|
||||
this.appConfig.viewerContainer.classList.add(ENABLE_PERMISSIONS_CLASS);
|
||||
}
|
||||
},
|
||||
|
||||
setInitialView(
|
||||
storedHash,
|
||||
{ rotation, sidebarView, scrollMode, spreadMode } = {}
|
||||
@ -1979,6 +2004,15 @@ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
|
||||
};
|
||||
}
|
||||
|
||||
function webViewerResetPermissions() {
|
||||
const { appConfig } = PDFViewerApplication;
|
||||
if (!appConfig) {
|
||||
return;
|
||||
}
|
||||
// Currently only the "copy"-permission is supported.
|
||||
appConfig.viewerContainer.classList.remove(ENABLE_PERMISSIONS_CLASS);
|
||||
}
|
||||
|
||||
function webViewerPageRendered(evt) {
|
||||
const pageNumber = evt.pageNumber;
|
||||
const pageIndex = pageNumber - 1;
|
||||
|
@ -53,6 +53,11 @@ const defaultOptions = {
|
||||
value: false,
|
||||
kind: OptionKind.VIEWER + OptionKind.PREFERENCE,
|
||||
},
|
||||
enablePermissions: {
|
||||
/** @type {boolean} */
|
||||
value: false,
|
||||
kind: OptionKind.VIEWER + OptionKind.PREFERENCE,
|
||||
},
|
||||
/**
|
||||
* The `disablePreferences` is, conditionally, defined below.
|
||||
*/
|
||||
|
@ -55,6 +55,11 @@ select {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.pdfViewer.enablePermissions .textLayer > span {
|
||||
user-select: none !important;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
#viewerContainer.pdfPresentationMode:-ms-fullscreen {
|
||||
top: 0px !important;
|
||||
overflow: hidden !important;
|
||||
|
Loading…
Reference in New Issue
Block a user