Merge pull request #3233 from yurydelendik/onpassword
Fixes password for range request loading
This commit is contained in:
commit
f07564b07f
26
src/api.js
26
src/api.js
@ -17,7 +17,7 @@
|
||||
/* globals CanvasGraphics, combineUrl, createScratchCanvas, error, ErrorFont,
|
||||
Font, FontLoader, globalScope, info, isArrayBuffer, loadJpegStream,
|
||||
MessageHandler, PDFJS, PDFObjects, Promise, StatTimer, warn,
|
||||
WorkerMessageHandler */
|
||||
WorkerMessageHandler, PasswordResponses */
|
||||
|
||||
'use strict';
|
||||
|
||||
@ -39,9 +39,16 @@
|
||||
* to manually serve range requests for data in the PDF. See viewer.js for
|
||||
* an example of pdfDataRangeTransport's interface.
|
||||
*
|
||||
* @param {function} passwordCallback is optional. It is used to request a
|
||||
* password if wrong or no password was provided. The callback receives two
|
||||
* parameters: function that needs to be called with new password and reason
|
||||
* (see {PasswordResponses}).
|
||||
*
|
||||
* @return {Promise} A promise that is resolved with {PDFDocumentProxy} object.
|
||||
*/
|
||||
PDFJS.getDocument = function getDocument(source, pdfDataRangeTransport) {
|
||||
PDFJS.getDocument = function getDocument(source,
|
||||
pdfDataRangeTransport,
|
||||
passwordCallback) {
|
||||
var workerInitializedPromise, workerReadyPromise, transport;
|
||||
|
||||
if (typeof source === 'string') {
|
||||
@ -71,6 +78,7 @@ PDFJS.getDocument = function getDocument(source, pdfDataRangeTransport) {
|
||||
transport = new WorkerTransport(workerInitializedPromise,
|
||||
workerReadyPromise, pdfDataRangeTransport);
|
||||
workerInitializedPromise.then(function transportInitialized() {
|
||||
transport.passwordCallback = passwordCallback;
|
||||
transport.fetchDocument(params);
|
||||
});
|
||||
return workerReadyPromise;
|
||||
@ -482,6 +490,8 @@ var WorkerTransport = (function WorkerTransportClosure() {
|
||||
this.pagePromises = [];
|
||||
this.embeddedFontsUsed = false;
|
||||
|
||||
this.passwordCallback = null;
|
||||
|
||||
// If worker support isn't disabled explicit and the browser has worker
|
||||
// support, create a new web worker and test if it/the browser fullfills
|
||||
// all requirements to run parts of pdf.js in a web worker.
|
||||
@ -559,6 +569,10 @@ var WorkerTransport = (function WorkerTransportClosure() {
|
||||
function WorkerTransport_setupMessageHandler(messageHandler) {
|
||||
this.messageHandler = messageHandler;
|
||||
|
||||
function updatePassword(password) {
|
||||
messageHandler.send('UpdatePassword', password);
|
||||
}
|
||||
|
||||
var pdfDataRangeTransport = this.pdfDataRangeTransport;
|
||||
if (pdfDataRangeTransport) {
|
||||
pdfDataRangeTransport.addRangeListener(function(begin, chunk) {
|
||||
@ -588,10 +602,18 @@ var WorkerTransport = (function WorkerTransportClosure() {
|
||||
}, this);
|
||||
|
||||
messageHandler.on('NeedPassword', function transportPassword(data) {
|
||||
if (this.passwordCallback) {
|
||||
return this.passwordCallback(updatePassword,
|
||||
PasswordResponses.NEED_PASSWORD);
|
||||
}
|
||||
this.workerReadyPromise.reject(data.exception.message, data.exception);
|
||||
}, this);
|
||||
|
||||
messageHandler.on('IncorrectPassword', function transportBadPass(data) {
|
||||
if (this.passwordCallback) {
|
||||
return this.passwordCallback(updatePassword,
|
||||
PasswordResponses.INCORRECT_PASSWORD);
|
||||
}
|
||||
this.workerReadyPromise.reject(data.exception.message, data.exception);
|
||||
}, this);
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
/* globals bytesToString, DecryptStream, error, isInt, isName, Name,
|
||||
PasswordException, stringToBytes */
|
||||
PasswordException, PasswordResponses, stringToBytes */
|
||||
|
||||
'use strict';
|
||||
|
||||
@ -575,7 +575,8 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
|
||||
ownerPassword, userPassword, flags,
|
||||
revision, keyLength, encryptMetadata);
|
||||
if (!encryptionKey && !password) {
|
||||
throw new PasswordException('No password given', 'needpassword');
|
||||
throw new PasswordException('No password given',
|
||||
PasswordResponses.NEED_PASSWORD);
|
||||
} else if (!encryptionKey && password) {
|
||||
// Attempting use the password as an owner password
|
||||
var decodedPassword = decodeUserPassword(passwordBytes, ownerPassword,
|
||||
@ -586,7 +587,8 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
|
||||
}
|
||||
|
||||
if (!encryptionKey)
|
||||
throw new PasswordException('Incorrect Password', 'incorrectpassword');
|
||||
throw new PasswordException('Incorrect Password',
|
||||
PasswordResponses.INCORRECT_PASSWORD);
|
||||
|
||||
this.encryptionKey = encryptionKey;
|
||||
|
||||
|
@ -56,6 +56,13 @@ var BasePdfManager = (function BasePdfManagerClosure() {
|
||||
|
||||
requestLoadedStream: function BasePdfManager_requestLoadedStream() {
|
||||
return new NotImplementedException();
|
||||
},
|
||||
|
||||
updatePassword: function BasePdfManager_updatePassword(password) {
|
||||
this.pdfModel.xref.password = this.password = password;
|
||||
if (this.passwordChangedPromise) {
|
||||
this.passwordChangedPromise.resolve();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -139,6 +139,11 @@ function shadow(obj, prop, value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
var PasswordResponses = PDFJS.PasswordResponses = {
|
||||
NEED_PASSWORD: 1,
|
||||
INCORRECT_PASSWORD: 2
|
||||
};
|
||||
|
||||
var PasswordException = (function PasswordExceptionClosure() {
|
||||
function PasswordException(msg, code) {
|
||||
this.name = 'PasswordException';
|
||||
|
@ -18,7 +18,7 @@
|
||||
MissingPDFException, PasswordException, PDFDocument, PDFJS, Promise,
|
||||
Stream, UnknownErrorException, warn, NetworkManager, LocalPdfManager,
|
||||
NetworkPdfManager, XRefParseException, NotImplementedException,
|
||||
isInt */
|
||||
isInt, PasswordResponses */
|
||||
|
||||
'use strict';
|
||||
|
||||
@ -267,11 +267,11 @@ var WorkerMessageHandler = {
|
||||
|
||||
var onFailure = function(e) {
|
||||
if (e instanceof PasswordException) {
|
||||
if (e.code === 'needpassword') {
|
||||
if (e.code === PasswordResponses.NEED_PASSWORD) {
|
||||
handler.send('NeedPassword', {
|
||||
exception: e
|
||||
});
|
||||
} else if (e.code === 'incorrectpassword') {
|
||||
} else if (e.code === PasswordResponses.INCORRECT_PASSWORD) {
|
||||
handler.send('IncorrectPassword', {
|
||||
exception: e
|
||||
});
|
||||
@ -291,10 +291,17 @@ var WorkerMessageHandler = {
|
||||
}
|
||||
};
|
||||
|
||||
getPdfManager(data).then(function() {
|
||||
loadDocument(false).then(onSuccess, function(ex) {
|
||||
getPdfManager(data).then(function pdfManagerReady() {
|
||||
loadDocument(false).then(onSuccess, function loadFailure(ex) {
|
||||
// Try again with recoveryMode == true
|
||||
if (!(ex instanceof XRefParseException)) {
|
||||
if (ex instanceof PasswordException) {
|
||||
// after password exception prepare to receive a new password
|
||||
// to repeat loading
|
||||
pdfManager.passwordChangedPromise = new Promise();
|
||||
pdfManager.passwordChangedPromise.then(pdfManagerReady);
|
||||
}
|
||||
|
||||
onFailure(ex);
|
||||
return;
|
||||
}
|
||||
@ -349,6 +356,10 @@ var WorkerMessageHandler = {
|
||||
});
|
||||
});
|
||||
|
||||
handler.on('UpdatePassword', function wphSetupUpdatePassword(data) {
|
||||
pdfManager.updatePassword(data);
|
||||
});
|
||||
|
||||
handler.on('GetAnnotationsRequest', function wphSetupGetAnnotations(data) {
|
||||
pdfManager.getPage(data.pageIndex).then(function(page) {
|
||||
pdfManager.ensure(page, 'getAnnotationsData', []).then(
|
||||
|
@ -1048,30 +1048,27 @@ var PDFView = {
|
||||
this.pdfDocument = null;
|
||||
var self = this;
|
||||
self.loading = true;
|
||||
PDFJS.getDocument(parameters, pdfDataRangeTransport).then(
|
||||
var passwordNeeded = function passwordNeeded(updatePassword, reason) {
|
||||
var promptString = mozL10n.get('request_password', null,
|
||||
'PDF is protected by a password:');
|
||||
|
||||
if (reason === PDFJS.PasswordResponses.INCORRECT_PASSWORD) {
|
||||
promptString += '\n' + mozL10n.get('invalid_password', null,
|
||||
'Invalid Password.');
|
||||
}
|
||||
|
||||
password = prompt(promptString);
|
||||
if (password && password.length > 0) {
|
||||
return updatePassword(password);
|
||||
}
|
||||
};
|
||||
|
||||
PDFJS.getDocument(parameters, pdfDataRangeTransport, passwordNeeded).then(
|
||||
function getDocumentCallback(pdfDocument) {
|
||||
self.load(pdfDocument, scale);
|
||||
self.loading = false;
|
||||
},
|
||||
function getDocumentError(message, exception) {
|
||||
if (exception && exception.name === 'PasswordException') {
|
||||
if (exception.code === 'needpassword' ||
|
||||
exception.code === 'incorrectpassword') {
|
||||
var promptString = mozL10n.get('request_password', null,
|
||||
'PDF is protected by a password:');
|
||||
|
||||
if (exception.code === 'incorrectpassword') {
|
||||
promptString += '\n' + mozL10n.get('invalid_password', null,
|
||||
'Invalid Password.');
|
||||
}
|
||||
|
||||
password = prompt(promptString);
|
||||
if (password && password.length > 0) {
|
||||
return PDFView.open(url, scale, password);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var loadingErrorMessage = mozL10n.get('loading_error', null,
|
||||
'An error occurred while loading the PDF.');
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user