Fixes password for range request loading
This commit is contained in:
parent
220c827e9e
commit
61a7738a5d
26
src/api.js
26
src/api.js
@ -17,7 +17,7 @@
|
|||||||
/* globals CanvasGraphics, combineUrl, createScratchCanvas, error, ErrorFont,
|
/* globals CanvasGraphics, combineUrl, createScratchCanvas, error, ErrorFont,
|
||||||
Font, FontLoader, globalScope, info, isArrayBuffer, loadJpegStream,
|
Font, FontLoader, globalScope, info, isArrayBuffer, loadJpegStream,
|
||||||
MessageHandler, PDFJS, PDFObjects, Promise, StatTimer, warn,
|
MessageHandler, PDFJS, PDFObjects, Promise, StatTimer, warn,
|
||||||
WorkerMessageHandler */
|
WorkerMessageHandler, PasswordResponses */
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
@ -39,9 +39,16 @@
|
|||||||
* to manually serve range requests for data in the PDF. See viewer.js for
|
* to manually serve range requests for data in the PDF. See viewer.js for
|
||||||
* an example of pdfDataRangeTransport's interface.
|
* 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.
|
* @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;
|
var workerInitializedPromise, workerReadyPromise, transport;
|
||||||
|
|
||||||
if (typeof source === 'string') {
|
if (typeof source === 'string') {
|
||||||
@ -71,6 +78,7 @@ PDFJS.getDocument = function getDocument(source, pdfDataRangeTransport) {
|
|||||||
transport = new WorkerTransport(workerInitializedPromise,
|
transport = new WorkerTransport(workerInitializedPromise,
|
||||||
workerReadyPromise, pdfDataRangeTransport);
|
workerReadyPromise, pdfDataRangeTransport);
|
||||||
workerInitializedPromise.then(function transportInitialized() {
|
workerInitializedPromise.then(function transportInitialized() {
|
||||||
|
transport.passwordCallback = passwordCallback;
|
||||||
transport.fetchDocument(params);
|
transport.fetchDocument(params);
|
||||||
});
|
});
|
||||||
return workerReadyPromise;
|
return workerReadyPromise;
|
||||||
@ -482,6 +490,8 @@ var WorkerTransport = (function WorkerTransportClosure() {
|
|||||||
this.pagePromises = [];
|
this.pagePromises = [];
|
||||||
this.embeddedFontsUsed = false;
|
this.embeddedFontsUsed = false;
|
||||||
|
|
||||||
|
this.passwordCallback = null;
|
||||||
|
|
||||||
// If worker support isn't disabled explicit and the browser has worker
|
// 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
|
// 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.
|
// all requirements to run parts of pdf.js in a web worker.
|
||||||
@ -559,6 +569,10 @@ var WorkerTransport = (function WorkerTransportClosure() {
|
|||||||
function WorkerTransport_setupMessageHandler(messageHandler) {
|
function WorkerTransport_setupMessageHandler(messageHandler) {
|
||||||
this.messageHandler = messageHandler;
|
this.messageHandler = messageHandler;
|
||||||
|
|
||||||
|
function updatePassword(password) {
|
||||||
|
messageHandler.send('UpdatePassword', password);
|
||||||
|
}
|
||||||
|
|
||||||
var pdfDataRangeTransport = this.pdfDataRangeTransport;
|
var pdfDataRangeTransport = this.pdfDataRangeTransport;
|
||||||
if (pdfDataRangeTransport) {
|
if (pdfDataRangeTransport) {
|
||||||
pdfDataRangeTransport.addRangeListener(function(begin, chunk) {
|
pdfDataRangeTransport.addRangeListener(function(begin, chunk) {
|
||||||
@ -588,10 +602,18 @@ var WorkerTransport = (function WorkerTransportClosure() {
|
|||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
messageHandler.on('NeedPassword', function transportPassword(data) {
|
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.workerReadyPromise.reject(data.exception.message, data.exception);
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
messageHandler.on('IncorrectPassword', function transportBadPass(data) {
|
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.workerReadyPromise.reject(data.exception.message, data.exception);
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
/* globals bytesToString, DecryptStream, error, isInt, isName, Name,
|
/* globals bytesToString, DecryptStream, error, isInt, isName, Name,
|
||||||
PasswordException, stringToBytes */
|
PasswordException, PasswordResponses, stringToBytes */
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
@ -575,7 +575,8 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
|
|||||||
ownerPassword, userPassword, flags,
|
ownerPassword, userPassword, flags,
|
||||||
revision, keyLength, encryptMetadata);
|
revision, keyLength, encryptMetadata);
|
||||||
if (!encryptionKey && !password) {
|
if (!encryptionKey && !password) {
|
||||||
throw new PasswordException('No password given', 'needpassword');
|
throw new PasswordException('No password given',
|
||||||
|
PasswordResponses.NEED_PASSWORD);
|
||||||
} else if (!encryptionKey && password) {
|
} else if (!encryptionKey && password) {
|
||||||
// Attempting use the password as an owner password
|
// Attempting use the password as an owner password
|
||||||
var decodedPassword = decodeUserPassword(passwordBytes, ownerPassword,
|
var decodedPassword = decodeUserPassword(passwordBytes, ownerPassword,
|
||||||
@ -586,7 +587,8 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!encryptionKey)
|
if (!encryptionKey)
|
||||||
throw new PasswordException('Incorrect Password', 'incorrectpassword');
|
throw new PasswordException('Incorrect Password',
|
||||||
|
PasswordResponses.INCORRECT_PASSWORD);
|
||||||
|
|
||||||
this.encryptionKey = encryptionKey;
|
this.encryptionKey = encryptionKey;
|
||||||
|
|
||||||
|
@ -56,6 +56,13 @@ var BasePdfManager = (function BasePdfManagerClosure() {
|
|||||||
|
|
||||||
requestLoadedStream: function BasePdfManager_requestLoadedStream() {
|
requestLoadedStream: function BasePdfManager_requestLoadedStream() {
|
||||||
return new NotImplementedException();
|
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;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var PasswordResponses = PDFJS.PasswordResponses = {
|
||||||
|
NEED_PASSWORD: 1,
|
||||||
|
INCORRECT_PASSWORD: 2
|
||||||
|
};
|
||||||
|
|
||||||
var PasswordException = (function PasswordExceptionClosure() {
|
var PasswordException = (function PasswordExceptionClosure() {
|
||||||
function PasswordException(msg, code) {
|
function PasswordException(msg, code) {
|
||||||
this.name = 'PasswordException';
|
this.name = 'PasswordException';
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
MissingPDFException, PasswordException, PDFDocument, PDFJS, Promise,
|
MissingPDFException, PasswordException, PDFDocument, PDFJS, Promise,
|
||||||
Stream, UnknownErrorException, warn, NetworkManager, LocalPdfManager,
|
Stream, UnknownErrorException, warn, NetworkManager, LocalPdfManager,
|
||||||
NetworkPdfManager, XRefParseException, NotImplementedException,
|
NetworkPdfManager, XRefParseException, NotImplementedException,
|
||||||
isInt */
|
isInt, PasswordResponses */
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
@ -267,11 +267,11 @@ var WorkerMessageHandler = {
|
|||||||
|
|
||||||
var onFailure = function(e) {
|
var onFailure = function(e) {
|
||||||
if (e instanceof PasswordException) {
|
if (e instanceof PasswordException) {
|
||||||
if (e.code === 'needpassword') {
|
if (e.code === PasswordResponses.NEED_PASSWORD) {
|
||||||
handler.send('NeedPassword', {
|
handler.send('NeedPassword', {
|
||||||
exception: e
|
exception: e
|
||||||
});
|
});
|
||||||
} else if (e.code === 'incorrectpassword') {
|
} else if (e.code === PasswordResponses.INCORRECT_PASSWORD) {
|
||||||
handler.send('IncorrectPassword', {
|
handler.send('IncorrectPassword', {
|
||||||
exception: e
|
exception: e
|
||||||
});
|
});
|
||||||
@ -291,10 +291,17 @@ var WorkerMessageHandler = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
getPdfManager(data).then(function() {
|
getPdfManager(data).then(function pdfManagerReady() {
|
||||||
loadDocument(false).then(onSuccess, function(ex) {
|
loadDocument(false).then(onSuccess, function loadFailure(ex) {
|
||||||
// Try again with recoveryMode == true
|
// Try again with recoveryMode == true
|
||||||
if (!(ex instanceof XRefParseException)) {
|
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);
|
onFailure(ex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -349,6 +356,10 @@ var WorkerMessageHandler = {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
handler.on('UpdatePassword', function wphSetupUpdatePassword(data) {
|
||||||
|
pdfManager.updatePassword(data);
|
||||||
|
});
|
||||||
|
|
||||||
handler.on('GetAnnotationsRequest', function wphSetupGetAnnotations(data) {
|
handler.on('GetAnnotationsRequest', function wphSetupGetAnnotations(data) {
|
||||||
pdfManager.getPage(data.pageIndex).then(function(page) {
|
pdfManager.getPage(data.pageIndex).then(function(page) {
|
||||||
pdfManager.ensure(page, 'getAnnotationsData', []).then(
|
pdfManager.ensure(page, 'getAnnotationsData', []).then(
|
||||||
|
@ -1048,30 +1048,27 @@ var PDFView = {
|
|||||||
this.pdfDocument = null;
|
this.pdfDocument = null;
|
||||||
var self = this;
|
var self = this;
|
||||||
self.loading = true;
|
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) {
|
function getDocumentCallback(pdfDocument) {
|
||||||
self.load(pdfDocument, scale);
|
self.load(pdfDocument, scale);
|
||||||
self.loading = false;
|
self.loading = false;
|
||||||
},
|
},
|
||||||
function getDocumentError(message, exception) {
|
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,
|
var loadingErrorMessage = mozL10n.get('loading_error', null,
|
||||||
'An error occurred while loading the PDF.');
|
'An error occurred while loading the PDF.');
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user