From af4debcfc3cf5f08937479819cbd376763ca10a7 Mon Sep 17 00:00:00 2001 From: tienifr Date: Fri, 24 May 2024 15:02:12 +0700 Subject: [PATCH 01/19] fix Password-protected PDF not handled correctly --- .../MoneyRequestConfirmationList.tsx | 1 - .../index.native.ts | 14 +++++++++++++ .../isPdfFilePasswordProtected/index.ts | 20 +++++++++++++++++++ .../step/IOURequestStepScan/index.native.tsx | 11 ++++++++++ .../request/step/IOURequestStepScan/index.tsx | 9 +++++++++ 5 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.native.ts create mode 100644 src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.ts diff --git a/src/components/MoneyRequestConfirmationList.tsx b/src/components/MoneyRequestConfirmationList.tsx index bb7e3ac4f78e..9953e7ddd14e 100755 --- a/src/components/MoneyRequestConfirmationList.tsx +++ b/src/components/MoneyRequestConfirmationList.tsx @@ -1096,7 +1096,6 @@ function MoneyRequestConfirmationList({ previewSourceURL={resolvedReceiptImage as string} // We don't support scanning password protected PDF receipt enabled={!isAttachmentInvalid} - onPassword={() => setIsAttachmentInvalid(true)} /> ) : ( { + try { + if (!file.uri) { + return false; + } + return false; + } catch (error) { + return false; + } +}; + +export default isPdfFilePasswordProtected; diff --git a/src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.ts b/src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.ts new file mode 100644 index 000000000000..c3bdad0536d6 --- /dev/null +++ b/src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.ts @@ -0,0 +1,20 @@ +import {pdfjs} from 'react-pdf'; +import type {FileObject} from '@components/AttachmentModal'; + +const isPdfFilePasswordProtected = (file: FileObject): Promise => + new Promise((resolve) => { + if (!file.uri) { + resolve(false); + } + + pdfjs.getDocument(file.uri ?? '').onPassword = (_callback: () => void, reason: number) => { + // 1 is the error code for password protected PDF error + if (reason === 1) { + resolve(true); + return; + } + resolve(false); + }; + }); + +export default isPdfFilePasswordProtected; diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx index c022a079df65..ce138c0af48e 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx @@ -22,6 +22,7 @@ import useLocalize from '@hooks/useLocalize'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import * as FileUtils from '@libs/fileDownload/FileUtils'; +import isPdfFilePasswordProtected from '@libs/focusComposerWithDelay/isPdfFilePasswordProtected'; import getCurrentPosition from '@libs/getCurrentPosition'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; @@ -173,6 +174,16 @@ function IOURequestStepScan({ Alert.alert(translate('attachmentPicker.attachmentTooSmall'), translate('attachmentPicker.sizeNotMet')); return false; } + + if (fileExtension === 'pdf') { + return isPdfFilePasswordProtected(file).then((isProtected: boolean) => { + if (isProtected) { + Alert.alert(translate('attachmentPicker.wrongFileType'), translate('attachmentPicker.protectedPDFNotSupported')); + } + return !isProtected; + }); + } + return true; }; diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.tsx index ede79e009a49..171f48741ee9 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.tsx @@ -23,6 +23,7 @@ import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import * as Browser from '@libs/Browser'; import * as FileUtils from '@libs/fileDownload/FileUtils'; +import isPdfFilePasswordProtected from '@libs/focusComposerWithDelay/isPdfFilePasswordProtected'; import getCurrentPosition from '@libs/getCurrentPosition'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; @@ -206,6 +207,14 @@ function IOURequestStepScan({ return false; } + if (fileExtension === 'pdf') { + return isPdfFilePasswordProtected(file).then((isProtected: boolean) => { + if (isProtected) { + setUploadReceiptError(true, 'attachmentPicker.wrongFileType', 'attachmentPicker.protectedPDFNotSupported'); + } + return !isProtected; + }); + } return true; }) .catch(() => { From b71c857e31152a3dfff14d3e666b3f9ccce9288f Mon Sep 17 00:00:00 2001 From: tienifr Date: Mon, 27 May 2024 18:22:48 +0700 Subject: [PATCH 02/19] fix native issue --- .../isPdfFilePasswordProtected/index.native.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.native.ts b/src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.native.ts index fde14ddfcb7f..5338b030f96c 100644 --- a/src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.native.ts +++ b/src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.native.ts @@ -1,12 +1,19 @@ +import * as RNFS from 'react-native-fs'; import type {FileObject} from '@components/AttachmentModal'; const isPdfFilePasswordProtected = async (file: FileObject) => { try { - if (!file.uri) { - return false; + // Ensure the file URI is properly formatted + const filePath = file.uri.replace('file://', ''); + // Check if the file exists + const fileExists = await RNFS.exists(filePath); + if (!fileExists) { + throw new Error(`File not found: ${filePath}`); } + return false; } catch (error) { + console.error('Error checking PDF password protection:', error); return false; } }; From 58d2aeba63d6ae8da5de4cd22333b03738dc6aee Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 30 May 2024 00:16:20 +0700 Subject: [PATCH 03/19] fix use pdf lib --- package-lock.json | 46 +++++++++++++------ package.json | 1 + .../index.native.ts | 21 --------- .../index.native.tsx | 20 ++++++++ .../{index.ts => index.tsx} | 0 .../step/IOURequestStepScan/index.native.tsx | 3 +- .../request/step/IOURequestStepScan/index.tsx | 3 +- 7 files changed, 58 insertions(+), 36 deletions(-) delete mode 100644 src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.native.ts create mode 100644 src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.native.tsx rename src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/{index.ts => index.tsx} (100%) diff --git a/package-lock.json b/package-lock.json index 71b6a72c0f92..c8e9fa0f126b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -72,6 +72,7 @@ "lottie-react-native": "6.5.1", "mapbox-gl": "^2.15.0", "onfido-sdk-ui": "14.15.0", + "pdf-lib": "^1.17.1", "process": "^0.11.10", "prop-types": "^15.7.2", "pusher-js": "8.3.0", @@ -1855,19 +1856,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-object-assign": { - "version": "7.18.6", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-transform-object-rest-spread": { "version": "7.24.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.1.tgz", @@ -7677,6 +7665,22 @@ "react-native": ">=0.70.0 <1.0.x" } }, + "node_modules/@pdf-lib/standard-fonts": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@pdf-lib/standard-fonts/-/standard-fonts-1.0.0.tgz", + "integrity": "sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA==", + "dependencies": { + "pako": "^1.0.6" + } + }, + "node_modules/@pdf-lib/upng": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@pdf-lib/upng/-/upng-1.0.1.tgz", + "integrity": "sha512-dQK2FUMQtowVP00mtIksrlZhdFXQZPC+taih1q4CvPZ5vqdxR/LKBaFg0oAfzd1GlHZXXSPdQfzQnt+ViGvEIQ==", + "dependencies": { + "pako": "^1.0.10" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "license": "MIT", @@ -30087,6 +30091,22 @@ "node": ">=0.12" } }, + "node_modules/pdf-lib": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/pdf-lib/-/pdf-lib-1.17.1.tgz", + "integrity": "sha512-V/mpyJAoTsN4cnP31vc0wfNA1+p20evqqnap0KLoRUN0Yk/p3wN52DOEsL4oBFcLdb76hlpKPtzJIgo67j/XLw==", + "dependencies": { + "@pdf-lib/standard-fonts": "^1.0.0", + "@pdf-lib/upng": "^1.0.1", + "pako": "^1.0.11", + "tslib": "^1.11.1" + } + }, + "node_modules/pdf-lib/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, "node_modules/pdfjs-dist": { "version": "3.11.174", "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-3.11.174.tgz", diff --git a/package.json b/package.json index 0666111e25c1..fa3009e7fcc6 100644 --- a/package.json +++ b/package.json @@ -124,6 +124,7 @@ "lottie-react-native": "6.5.1", "mapbox-gl": "^2.15.0", "onfido-sdk-ui": "14.15.0", + "pdf-lib": "^1.17.1", "process": "^0.11.10", "prop-types": "^15.7.2", "pusher-js": "8.3.0", diff --git a/src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.native.ts b/src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.native.ts deleted file mode 100644 index 5338b030f96c..000000000000 --- a/src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.native.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as RNFS from 'react-native-fs'; -import type {FileObject} from '@components/AttachmentModal'; - -const isPdfFilePasswordProtected = async (file: FileObject) => { - try { - // Ensure the file URI is properly formatted - const filePath = file.uri.replace('file://', ''); - // Check if the file exists - const fileExists = await RNFS.exists(filePath); - if (!fileExists) { - throw new Error(`File not found: ${filePath}`); - } - - return false; - } catch (error) { - console.error('Error checking PDF password protection:', error); - return false; - } -}; - -export default isPdfFilePasswordProtected; diff --git a/src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.native.tsx b/src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.native.tsx new file mode 100644 index 000000000000..60302e8d4bbe --- /dev/null +++ b/src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.native.tsx @@ -0,0 +1,20 @@ +import {PDFDocument} from 'pdf-lib'; +import RNFetchBlob from 'react-native-blob-util'; +import {FileObject} from '@components/AttachmentModal'; + +const isPdfFilePasswordProtected = async (file: FileObject) => { + try { + if (!file.uri) { + return false; + } + const filePath = file.uri.replace('file://', ''); + const pdfBytes = await RNFetchBlob.fs.readFile(filePath, 'base64'); + const pdfDoc = await PDFDocument.load(pdfBytes, {ignoreEncryption: true}); + const isEncrypted = pdfDoc.isEncrypted; + return isEncrypted; + } catch (error) { + return false; + } +}; + +export default isPdfFilePasswordProtected; diff --git a/src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.ts b/src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.tsx similarity index 100% rename from src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.ts rename to src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.tsx diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx index 86350931eb6e..b241bc07b8b3 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx @@ -179,8 +179,9 @@ function IOURequestStepScan({ return isPdfFilePasswordProtected(file).then((isProtected: boolean) => { if (isProtected) { Alert.alert(translate('attachmentPicker.wrongFileType'), translate('attachmentPicker.protectedPDFNotSupported')); + return false; } - return !isProtected; + return true; }); } diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.tsx index 171f48741ee9..15e141779819 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.tsx @@ -211,8 +211,9 @@ function IOURequestStepScan({ return isPdfFilePasswordProtected(file).then((isProtected: boolean) => { if (isProtected) { setUploadReceiptError(true, 'attachmentPicker.wrongFileType', 'attachmentPicker.protectedPDFNotSupported'); + return false; } - return !isProtected; + return true; }); } return true; From cdedb547d286df621e03784eddffe9207be84446 Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 30 May 2024 00:46:46 +0700 Subject: [PATCH 04/19] fix validateReceipt function --- .../step/IOURequestStepScan/index.native.tsx | 83 ++++++++++--------- 1 file changed, 44 insertions(+), 39 deletions(-) diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx index b241bc07b8b3..b300766d78d2 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx @@ -156,36 +156,40 @@ function IOURequestStepScan({ }, []), ); - const validateReceipt = (file: FileObject) => { - const {fileExtension} = FileUtils.splitExtensionFromFileName(file?.name ?? ''); - if ( - !CONST.API_ATTACHMENT_VALIDATIONS.ALLOWED_RECEIPT_EXTENSIONS.includes(fileExtension.toLowerCase() as (typeof CONST.API_ATTACHMENT_VALIDATIONS.ALLOWED_RECEIPT_EXTENSIONS)[number]) - ) { - Alert.alert(translate('attachmentPicker.wrongFileType'), translate('attachmentPicker.notAllowedExtension')); - return false; - } + const validateReceipt = (file: FileObject): Promise => { + return new Promise((resolve) => { + const {fileExtension} = FileUtils.splitExtensionFromFileName(file?.name ?? ''); + if ( + !CONST.API_ATTACHMENT_VALIDATIONS.ALLOWED_RECEIPT_EXTENSIONS.includes( + fileExtension.toLowerCase() as (typeof CONST.API_ATTACHMENT_VALIDATIONS.ALLOWED_RECEIPT_EXTENSIONS)[number], + ) + ) { + Alert.alert(translate('attachmentPicker.wrongFileType'), translate('attachmentPicker.notAllowedExtension')); + resolve(false); + } - if ((file?.size ?? 0) > CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE) { - Alert.alert(translate('attachmentPicker.attachmentTooLarge'), translate('attachmentPicker.sizeExceeded')); - return false; - } + if ((file?.size ?? 0) > CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE) { + Alert.alert(translate('attachmentPicker.attachmentTooLarge'), translate('attachmentPicker.sizeExceeded')); + resolve(false); + } - if ((file?.size ?? 0) < CONST.API_ATTACHMENT_VALIDATIONS.MIN_SIZE) { - Alert.alert(translate('attachmentPicker.attachmentTooSmall'), translate('attachmentPicker.sizeNotMet')); - return false; - } + if ((file?.size ?? 0) < CONST.API_ATTACHMENT_VALIDATIONS.MIN_SIZE) { + Alert.alert(translate('attachmentPicker.attachmentTooSmall'), translate('attachmentPicker.sizeNotMet')); + resolve(false); + } - if (fileExtension === 'pdf') { - return isPdfFilePasswordProtected(file).then((isProtected: boolean) => { - if (isProtected) { - Alert.alert(translate('attachmentPicker.wrongFileType'), translate('attachmentPicker.protectedPDFNotSupported')); - return false; - } - return true; - }); - } + if (fileExtension === 'pdf') { + return isPdfFilePasswordProtected(file).then((isProtected: boolean) => { + if (isProtected) { + Alert.alert(translate('attachmentPicker.wrongFileType'), translate('attachmentPicker.protectedPDFNotSupported')); + resolve(false); + } + resolve(true); + }); + } - return true; + resolve(true); + }); }; const navigateBack = () => { @@ -380,21 +384,22 @@ function IOURequestStepScan({ * Sets the Receipt objects and navigates the user to the next page */ const setReceiptAndNavigate = (file: FileObject) => { - if (!validateReceipt(file)) { - return; - } - - // Store the receipt on the transaction object in Onyx - // On Android devices, fetching blob for a file with name containing spaces fails to retrieve the type of file. - // So, let us also save the file type in receipt for later use during blob fetch - IOU.setMoneyRequestReceipt(transactionID, file?.uri ?? '', file.name ?? '', action !== CONST.IOU.ACTION.EDIT, file.type); + validateReceipt(file).then((isFileValid) => { + if (!isFileValid) { + return; + } + // Store the receipt on the transaction object in Onyx + // On Android devices, fetching blob for a file with name containing spaces fails to retrieve the type of file. + // So, let us also save the file type in receipt for later use during blob fetch + IOU.setMoneyRequestReceipt(transactionID, file?.uri ?? '', file.name ?? '', action !== CONST.IOU.ACTION.EDIT, file.type); - if (action === CONST.IOU.ACTION.EDIT) { - updateScanAndNavigate(file, file?.uri ?? ''); - return; - } + if (action === CONST.IOU.ACTION.EDIT) { + updateScanAndNavigate(file, file?.uri ?? ''); + return; + } - navigateToConfirmationStep(file, file.uri ?? ''); + navigateToConfirmationStep(file, file.uri ?? ''); + }); }; const capturePhoto = useCallback(() => { From 084f8958d6efce83f6e392fa1980568edfb80782 Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 30 May 2024 01:21:31 +0700 Subject: [PATCH 05/19] fix lint --- .../MoneyRequestConfirmationList.tsx | 33 +------------------ .../index.native.tsx | 25 +++++++------- .../step/IOURequestStepScan/index.native.tsx | 14 ++++---- 3 files changed, 21 insertions(+), 51 deletions(-) diff --git a/src/components/MoneyRequestConfirmationList.tsx b/src/components/MoneyRequestConfirmationList.tsx index 9953e7ddd14e..8710954bca47 100755 --- a/src/components/MoneyRequestConfirmationList.tsx +++ b/src/components/MoneyRequestConfirmationList.tsx @@ -44,7 +44,6 @@ import type {SplitShares} from '@src/types/onyx/Transaction'; import ButtonWithDropdownMenu from './ButtonWithDropdownMenu'; import type {DropdownOption} from './ButtonWithDropdownMenu/types'; import ConfirmedRoute from './ConfirmedRoute'; -import ConfirmModal from './ConfirmModal'; import FormHelpMessage from './FormHelpMessage'; import MenuItem from './MenuItem'; import MenuItemWithTopDescription from './MenuItemWithTopDescription'; @@ -324,13 +323,6 @@ function MoneyRequestConfirmationList({ const [didConfirm, setDidConfirm] = useState(false); const [didConfirmSplit, setDidConfirmSplit] = useState(false); - const [isAttachmentInvalid, setIsAttachmentInvalid] = useState(false); - - const navigateBack = useCallback( - () => Navigation.goBack(ROUTES.MONEY_REQUEST_CREATE_TAB_SCAN.getRoute(CONST.IOU.ACTION.CREATE, iouType, transactionID, reportID)), - [iouType, reportID, transactionID], - ); - const shouldDisplayFieldError: boolean = useMemo(() => { if (!isEditingSplitBill) { return false; @@ -1095,7 +1087,6 @@ function MoneyRequestConfirmationList({ // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style previewSourceURL={resolvedReceiptImage as string} // We don't support scanning password protected PDF receipt - enabled={!isAttachmentInvalid} /> ) : ( ), - [ - isLocalFile, - receiptFilename, - resolvedThumbnail, - styles.moneyRequestImage, - isAttachmentInvalid, - isThumbnail, - resolvedReceiptImage, - receiptThumbnail, - fileExtension, - isDistanceRequest, - ], + [isLocalFile, receiptFilename, resolvedThumbnail, styles.moneyRequestImage, isThumbnail, resolvedReceiptImage, receiptThumbnail, fileExtension, isDistanceRequest], ); const listFooterContent = useMemo( @@ -1180,26 +1160,15 @@ function MoneyRequestConfirmationList({ /> )} {shouldShowAllFields && supplementaryFields} - ), [ canUpdateSenderWorkspace, didConfirm, iouType, - isAttachmentInvalid, isDistanceRequest, isReadOnly, isTypeInvoice, - navigateBack, policy, primaryFields, receiptImage, diff --git a/src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.native.tsx b/src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.native.tsx index 60302e8d4bbe..d41feabf4900 100644 --- a/src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.native.tsx +++ b/src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.native.tsx @@ -1,20 +1,21 @@ import {PDFDocument} from 'pdf-lib'; import RNFetchBlob from 'react-native-blob-util'; -import {FileObject} from '@components/AttachmentModal'; +import type {FileObject} from '@components/AttachmentModal'; -const isPdfFilePasswordProtected = async (file: FileObject) => { - try { +const isPdfFilePasswordProtected = (file: FileObject) => + new Promise((resolve) => { if (!file.uri) { - return false; + resolve(false); + return; } + const filePath = file.uri.replace('file://', ''); - const pdfBytes = await RNFetchBlob.fs.readFile(filePath, 'base64'); - const pdfDoc = await PDFDocument.load(pdfBytes, {ignoreEncryption: true}); - const isEncrypted = pdfDoc.isEncrypted; - return isEncrypted; - } catch (error) { - return false; - } -}; + + RNFetchBlob.fs + .readFile(filePath, 'base64') + .then((pdfBytes: string | Uint8Array | ArrayBuffer) => PDFDocument.load(pdfBytes, {ignoreEncryption: true})) + .then((pdfDoc) => resolve(pdfDoc.isEncrypted)) + .catch(() => resolve(false)); + }); export default isPdfFilePasswordProtected; diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx index b300766d78d2..a05b599a0df4 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx @@ -156,8 +156,8 @@ function IOURequestStepScan({ }, []), ); - const validateReceipt = (file: FileObject): Promise => { - return new Promise((resolve) => { + const validateReceipt = (file: FileObject): Promise => + new Promise((resolve) => { const {fileExtension} = FileUtils.splitExtensionFromFileName(file?.name ?? ''); if ( !CONST.API_ATTACHMENT_VALIDATIONS.ALLOWED_RECEIPT_EXTENSIONS.includes( @@ -179,18 +179,18 @@ function IOURequestStepScan({ } if (fileExtension === 'pdf') { - return isPdfFilePasswordProtected(file).then((isProtected: boolean) => { + isPdfFilePasswordProtected(file).then((isProtected: boolean) => { if (isProtected) { Alert.alert(translate('attachmentPicker.wrongFileType'), translate('attachmentPicker.protectedPDFNotSupported')); resolve(false); + } else { + resolve(true); } - resolve(true); }); + } else { + resolve(true); } - - resolve(true); }); - }; const navigateBack = () => { Navigation.goBack(); From ab940b58fec68377157e75ade385be8578f8f519 Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 30 May 2024 01:28:16 +0700 Subject: [PATCH 06/19] fix import issue --- .../isPdfFilePasswordProtected/index.native.tsx | 0 .../isPdfFilePasswordProtected/index.tsx | 0 src/pages/iou/request/step/IOURequestStepScan/index.native.tsx | 2 +- src/pages/iou/request/step/IOURequestStepScan/index.tsx | 2 +- 4 files changed, 2 insertions(+), 2 deletions(-) rename src/libs/{focusComposerWithDelay => }/isPdfFilePasswordProtected/index.native.tsx (100%) rename src/libs/{focusComposerWithDelay => }/isPdfFilePasswordProtected/index.tsx (100%) diff --git a/src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.native.tsx b/src/libs/isPdfFilePasswordProtected/index.native.tsx similarity index 100% rename from src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.native.tsx rename to src/libs/isPdfFilePasswordProtected/index.native.tsx diff --git a/src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.tsx b/src/libs/isPdfFilePasswordProtected/index.tsx similarity index 100% rename from src/libs/focusComposerWithDelay/isPdfFilePasswordProtected/index.tsx rename to src/libs/isPdfFilePasswordProtected/index.tsx diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx index a05b599a0df4..7b672946e977 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx @@ -22,7 +22,7 @@ import useLocalize from '@hooks/useLocalize'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import * as FileUtils from '@libs/fileDownload/FileUtils'; -import isPdfFilePasswordProtected from '@libs/focusComposerWithDelay/isPdfFilePasswordProtected'; +import isPdfFilePasswordProtected from '@libs/isPdfFilePasswordProtected'; import getCurrentPosition from '@libs/getCurrentPosition'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.tsx index 15e141779819..3817d6105268 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.tsx @@ -23,8 +23,8 @@ import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import * as Browser from '@libs/Browser'; import * as FileUtils from '@libs/fileDownload/FileUtils'; -import isPdfFilePasswordProtected from '@libs/focusComposerWithDelay/isPdfFilePasswordProtected'; import getCurrentPosition from '@libs/getCurrentPosition'; +import isPdfFilePasswordProtected from '@libs/isPdfFilePasswordProtected'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; From 7c135f370285df76264a352c9f05f33f7d40a9ca Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 30 May 2024 01:30:55 +0700 Subject: [PATCH 07/19] fix package lock file --- package-lock.json | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/package-lock.json b/package-lock.json index c8e9fa0f126b..423f3b926892 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1856,6 +1856,19 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-object-assign": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-transform-object-rest-spread": { "version": "7.24.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.1.tgz", From 09d50db0e9257bb288257c0625725b2664b7b4f3 Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 30 May 2024 02:17:43 +0700 Subject: [PATCH 08/19] fix do not use react pdf in web --- src/libs/isPdfFilePasswordProtected/index.tsx | 32 +++++++++++++------ .../step/IOURequestStepScan/index.native.tsx | 2 +- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/libs/isPdfFilePasswordProtected/index.tsx b/src/libs/isPdfFilePasswordProtected/index.tsx index c3bdad0536d6..a291dde9099c 100644 --- a/src/libs/isPdfFilePasswordProtected/index.tsx +++ b/src/libs/isPdfFilePasswordProtected/index.tsx @@ -1,20 +1,32 @@ -import {pdfjs} from 'react-pdf'; +import {PDFDocument} from 'pdf-lib'; import type {FileObject} from '@components/AttachmentModal'; -const isPdfFilePasswordProtected = (file: FileObject): Promise => - new Promise((resolve) => { - if (!file.uri) { - resolve(false); - } +const isPdfFilePasswordProtected = (file: FileObject) => { + return new Promise((resolve, reject) => { + const reader = new FileReader(); - pdfjs.getDocument(file.uri ?? '').onPassword = (_callback: () => void, reason: number) => { - // 1 is the error code for password protected PDF error - if (reason === 1) { - resolve(true); + reader.onload = (event) => { + const arrayBuffer = event.target?.result; + if (!arrayBuffer) { + resolve(false); return; } + + PDFDocument.load(arrayBuffer, {ignoreEncryption: true}) + .then((pdfDoc) => { + resolve(pdfDoc.isEncrypted); + }) + .catch(() => { + resolve(false); + }); + }; + + reader.onerror = (error) => { resolve(false); }; + + reader.readAsArrayBuffer(file as File); }); +}; export default isPdfFilePasswordProtected; diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx index 7b672946e977..cf90c5a5303f 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx @@ -22,8 +22,8 @@ import useLocalize from '@hooks/useLocalize'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import * as FileUtils from '@libs/fileDownload/FileUtils'; -import isPdfFilePasswordProtected from '@libs/isPdfFilePasswordProtected'; import getCurrentPosition from '@libs/getCurrentPosition'; +import isPdfFilePasswordProtected from '@libs/isPdfFilePasswordProtected'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; From bd9e6c2d40d497fcc827dc146b4dbeca8f294596 Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 30 May 2024 02:23:50 +0700 Subject: [PATCH 09/19] fix typecheck --- src/libs/isPdfFilePasswordProtected/index.native.tsx | 2 +- src/libs/isPdfFilePasswordProtected/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/isPdfFilePasswordProtected/index.native.tsx b/src/libs/isPdfFilePasswordProtected/index.native.tsx index d41feabf4900..56b1fb067e33 100644 --- a/src/libs/isPdfFilePasswordProtected/index.native.tsx +++ b/src/libs/isPdfFilePasswordProtected/index.native.tsx @@ -2,7 +2,7 @@ import {PDFDocument} from 'pdf-lib'; import RNFetchBlob from 'react-native-blob-util'; import type {FileObject} from '@components/AttachmentModal'; -const isPdfFilePasswordProtected = (file: FileObject) => +const isPdfFilePasswordProtected = (file: FileObject): Promise => new Promise((resolve) => { if (!file.uri) { resolve(false); diff --git a/src/libs/isPdfFilePasswordProtected/index.tsx b/src/libs/isPdfFilePasswordProtected/index.tsx index a291dde9099c..ecd6e218fd75 100644 --- a/src/libs/isPdfFilePasswordProtected/index.tsx +++ b/src/libs/isPdfFilePasswordProtected/index.tsx @@ -1,7 +1,7 @@ import {PDFDocument} from 'pdf-lib'; import type {FileObject} from '@components/AttachmentModal'; -const isPdfFilePasswordProtected = (file: FileObject) => { +const isPdfFilePasswordProtected = (file: FileObject): Promise => { return new Promise((resolve, reject) => { const reader = new FileReader(); From ca0ca5806b63ece7b38056fd66f9164a0ca3c781 Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 30 May 2024 02:35:59 +0700 Subject: [PATCH 10/19] fix lint --- src/libs/isPdfFilePasswordProtected/index.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/libs/isPdfFilePasswordProtected/index.tsx b/src/libs/isPdfFilePasswordProtected/index.tsx index ecd6e218fd75..c7d9ea8ee631 100644 --- a/src/libs/isPdfFilePasswordProtected/index.tsx +++ b/src/libs/isPdfFilePasswordProtected/index.tsx @@ -1,8 +1,8 @@ import {PDFDocument} from 'pdf-lib'; import type {FileObject} from '@components/AttachmentModal'; -const isPdfFilePasswordProtected = (file: FileObject): Promise => { - return new Promise((resolve, reject) => { +const isPdfFilePasswordProtected = (file: FileObject): Promise => + new Promise((resolve) => { const reader = new FileReader(); reader.onload = (event) => { @@ -21,12 +21,11 @@ const isPdfFilePasswordProtected = (file: FileObject): Promise => { }); }; - reader.onerror = (error) => { + reader.onerror = () => { resolve(false); }; reader.readAsArrayBuffer(file as File); }); -}; export default isPdfFilePasswordProtected; From 30a4a03602891b3fda288a686321958649754503 Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 6 Jun 2024 15:17:33 +0700 Subject: [PATCH 11/19] fix lint --- src/components/MoneyRequestConfirmationList.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/MoneyRequestConfirmationList.tsx b/src/components/MoneyRequestConfirmationList.tsx index 6d3cf8e5b19f..0386be1088f6 100755 --- a/src/components/MoneyRequestConfirmationList.tsx +++ b/src/components/MoneyRequestConfirmationList.tsx @@ -45,6 +45,7 @@ import type {SplitShares} from '@src/types/onyx/Transaction'; import ButtonWithDropdownMenu from './ButtonWithDropdownMenu'; import type {DropdownOption} from './ButtonWithDropdownMenu/types'; import ConfirmedRoute from './ConfirmedRoute'; +import ConfirmModal from './ConfirmModal'; import FormHelpMessage from './FormHelpMessage'; import MenuItem from './MenuItem'; import MenuItemWithTopDescription from './MenuItemWithTopDescription'; @@ -1233,6 +1234,7 @@ function MoneyRequestConfirmationList({ transactionID, translate, invalidAttachmentPromt, + isAttachmentInvalid, ], ); From ff9bcf478a1df6b21673ed4a6e09c4a3eecfade5 Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 6 Jun 2024 15:26:37 +0700 Subject: [PATCH 12/19] fix lint --- src/components/MoneyRequestConfirmationList.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/MoneyRequestConfirmationList.tsx b/src/components/MoneyRequestConfirmationList.tsx index 0386be1088f6..ba5c65a4fbd6 100755 --- a/src/components/MoneyRequestConfirmationList.tsx +++ b/src/components/MoneyRequestConfirmationList.tsx @@ -1209,9 +1209,11 @@ function MoneyRequestConfirmationList({ canUpdateSenderWorkspace, didConfirm, iouType, + isAttachmentInvalid, isDistanceRequest, isReadOnly, isTypeInvoice, + navigateBack, policy, primaryFields, receiptImage, @@ -1234,7 +1236,6 @@ function MoneyRequestConfirmationList({ transactionID, translate, invalidAttachmentPromt, - isAttachmentInvalid, ], ); From 6a42d19cd39599f9140196a43dd8b6b131852eb9 Mon Sep 17 00:00:00 2001 From: tienifr Date: Sat, 8 Jun 2024 16:46:47 +0700 Subject: [PATCH 13/19] fix remove native fix --- .../index.native.tsx | 21 ----- src/libs/isPdfFilePasswordProtected/index.tsx | 45 ++++++----- .../step/IOURequestStepScan/index.native.tsx | 78 ++++++++----------- 3 files changed, 57 insertions(+), 87 deletions(-) delete mode 100644 src/libs/isPdfFilePasswordProtected/index.native.tsx diff --git a/src/libs/isPdfFilePasswordProtected/index.native.tsx b/src/libs/isPdfFilePasswordProtected/index.native.tsx deleted file mode 100644 index 56b1fb067e33..000000000000 --- a/src/libs/isPdfFilePasswordProtected/index.native.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import {PDFDocument} from 'pdf-lib'; -import RNFetchBlob from 'react-native-blob-util'; -import type {FileObject} from '@components/AttachmentModal'; - -const isPdfFilePasswordProtected = (file: FileObject): Promise => - new Promise((resolve) => { - if (!file.uri) { - resolve(false); - return; - } - - const filePath = file.uri.replace('file://', ''); - - RNFetchBlob.fs - .readFile(filePath, 'base64') - .then((pdfBytes: string | Uint8Array | ArrayBuffer) => PDFDocument.load(pdfBytes, {ignoreEncryption: true})) - .then((pdfDoc) => resolve(pdfDoc.isEncrypted)) - .catch(() => resolve(false)); - }); - -export default isPdfFilePasswordProtected; diff --git a/src/libs/isPdfFilePasswordProtected/index.tsx b/src/libs/isPdfFilePasswordProtected/index.tsx index c7d9ea8ee631..12112b4fa6e9 100644 --- a/src/libs/isPdfFilePasswordProtected/index.tsx +++ b/src/libs/isPdfFilePasswordProtected/index.tsx @@ -1,31 +1,38 @@ -import {PDFDocument} from 'pdf-lib'; -import type {FileObject} from '@components/AttachmentModal'; +import * as pdfjsLib from 'pdfjs-dist/build/pdf'; -const isPdfFilePasswordProtected = (file: FileObject): Promise => - new Promise((resolve) => { +const isPdfFilePasswordProtected = (file) => { + return new Promise((resolve, reject) => { const reader = new FileReader(); - reader.onload = (event) => { + reader.onload = async (event) => { const arrayBuffer = event.target?.result; - if (!arrayBuffer) { - resolve(false); - return; - } - PDFDocument.load(arrayBuffer, {ignoreEncryption: true}) - .then((pdfDoc) => { - resolve(pdfDoc.isEncrypted); - }) - .catch(() => { - resolve(false); - }); + try { + const loadingTask = pdfjsLib.getDocument({data: arrayBuffer}); + loadingTask.promise.then( + () => { + resolve(false); + }, + (error) => { + console.log('***********', error); + if (error.name === 'PasswordException') { + resolve(true); + } else { + reject(error); + } + }, + ); + } catch (error) { + reject(error); + } }; - reader.onerror = () => { - resolve(false); + reader.onerror = (error) => { + reject(error); }; - reader.readAsArrayBuffer(file as File); + reader.readAsArrayBuffer(file); }); +}; export default isPdfFilePasswordProtected; diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx index 3f6f5a24471b..7a4f7d08ca34 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx @@ -161,41 +161,26 @@ function IOURequestStepScan({ }, []), ); - const validateReceipt = (file: FileObject): Promise => - new Promise((resolve) => { - const {fileExtension} = FileUtils.splitExtensionFromFileName(file?.name ?? ''); - if ( - !CONST.API_ATTACHMENT_VALIDATIONS.ALLOWED_RECEIPT_EXTENSIONS.includes( - fileExtension.toLowerCase() as (typeof CONST.API_ATTACHMENT_VALIDATIONS.ALLOWED_RECEIPT_EXTENSIONS)[number], - ) - ) { - Alert.alert(translate('attachmentPicker.wrongFileType'), translate('attachmentPicker.notAllowedExtension')); - resolve(false); - } - - if ((file?.size ?? 0) > CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE) { - Alert.alert(translate('attachmentPicker.attachmentTooLarge'), translate('attachmentPicker.sizeExceeded')); - resolve(false); - } + const validateReceipt = (file: FileObject) => { + const {fileExtension} = FileUtils.splitExtensionFromFileName(file?.name ?? ''); + if ( + !CONST.API_ATTACHMENT_VALIDATIONS.ALLOWED_RECEIPT_EXTENSIONS.includes(fileExtension.toLowerCase() as (typeof CONST.API_ATTACHMENT_VALIDATIONS.ALLOWED_RECEIPT_EXTENSIONS)[number]) + ) { + Alert.alert(translate('attachmentPicker.wrongFileType'), translate('attachmentPicker.notAllowedExtension')); + return false; + } - if ((file?.size ?? 0) < CONST.API_ATTACHMENT_VALIDATIONS.MIN_SIZE) { - Alert.alert(translate('attachmentPicker.attachmentTooSmall'), translate('attachmentPicker.sizeNotMet')); - resolve(false); - } + if ((file?.size ?? 0) > CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE) { + Alert.alert(translate('attachmentPicker.attachmentTooLarge'), translate('attachmentPicker.sizeExceeded')); + return false; + } - if (fileExtension === 'pdf') { - isPdfFilePasswordProtected(file).then((isProtected: boolean) => { - if (isProtected) { - Alert.alert(translate('attachmentPicker.wrongFileType'), translate('attachmentPicker.protectedPDFNotSupported')); - resolve(false); - } else { - resolve(true); - } - }); - } else { - resolve(true); - } - }); + if ((file?.size ?? 0) < CONST.API_ATTACHMENT_VALIDATIONS.MIN_SIZE) { + Alert.alert(translate('attachmentPicker.attachmentTooSmall'), translate('attachmentPicker.sizeNotMet')); + return false; + } + return true; + }; const navigateBack = () => { Navigation.goBack(); @@ -393,22 +378,21 @@ function IOURequestStepScan({ * Sets the Receipt objects and navigates the user to the next page */ const setReceiptAndNavigate = (file: FileObject) => { - validateReceipt(file).then((isFileValid) => { - if (!isFileValid) { - return; - } - // Store the receipt on the transaction object in Onyx - // On Android devices, fetching blob for a file with name containing spaces fails to retrieve the type of file. - // So, let us also save the file type in receipt for later use during blob fetch - IOU.setMoneyRequestReceipt(transactionID, file?.uri ?? '', file.name ?? '', action !== CONST.IOU.ACTION.EDIT, file.type); + if (!validateReceipt(file)) { + return; + } - if (action === CONST.IOU.ACTION.EDIT) { - updateScanAndNavigate(file, file?.uri ?? ''); - return; - } + // Store the receipt on the transaction object in Onyx + // On Android devices, fetching blob for a file with name containing spaces fails to retrieve the type of file. + // So, let us also save the file type in receipt for later use during blob fetch + IOU.setMoneyRequestReceipt(transactionID, file?.uri ?? '', file.name ?? '', action !== CONST.IOU.ACTION.EDIT, file.type); - navigateToConfirmationStep(file, file.uri ?? ''); - }); + if (action === CONST.IOU.ACTION.EDIT) { + updateScanAndNavigate(file, file?.uri ?? ''); + return; + } + + navigateToConfirmationStep(file, file.uri ?? ''); }; const capturePhoto = useCallback(() => { From 6e44eb6d5a98f36013cf2b577c7caf2b7c007b93 Mon Sep 17 00:00:00 2001 From: tienifr Date: Sat, 8 Jun 2024 16:49:31 +0700 Subject: [PATCH 14/19] fix remove lib --- package-lock.json | 33 ------------------- package.json | 1 - .../step/IOURequestStepScan/index.native.tsx | 1 - 3 files changed, 35 deletions(-) diff --git a/package-lock.json b/package-lock.json index 58db911b8139..d972d33f7c27 100644 --- a/package-lock.json +++ b/package-lock.json @@ -72,7 +72,6 @@ "lottie-react-native": "6.5.1", "mapbox-gl": "^2.15.0", "onfido-sdk-ui": "14.15.0", - "pdf-lib": "^1.17.1", "process": "^0.11.10", "pusher-js": "8.3.0", "react": "18.2.0", @@ -7659,22 +7658,6 @@ "react-native": ">=0.70.0 <1.0.x" } }, - "node_modules/@pdf-lib/standard-fonts": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@pdf-lib/standard-fonts/-/standard-fonts-1.0.0.tgz", - "integrity": "sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA==", - "dependencies": { - "pako": "^1.0.6" - } - }, - "node_modules/@pdf-lib/upng": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@pdf-lib/upng/-/upng-1.0.1.tgz", - "integrity": "sha512-dQK2FUMQtowVP00mtIksrlZhdFXQZPC+taih1q4CvPZ5vqdxR/LKBaFg0oAfzd1GlHZXXSPdQfzQnt+ViGvEIQ==", - "dependencies": { - "pako": "^1.0.10" - } - }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "license": "MIT", @@ -30086,22 +30069,6 @@ "node": ">=0.12" } }, - "node_modules/pdf-lib": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/pdf-lib/-/pdf-lib-1.17.1.tgz", - "integrity": "sha512-V/mpyJAoTsN4cnP31vc0wfNA1+p20evqqnap0KLoRUN0Yk/p3wN52DOEsL4oBFcLdb76hlpKPtzJIgo67j/XLw==", - "dependencies": { - "@pdf-lib/standard-fonts": "^1.0.0", - "@pdf-lib/upng": "^1.0.1", - "pako": "^1.0.11", - "tslib": "^1.11.1" - } - }, - "node_modules/pdf-lib/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, "node_modules/pdfjs-dist": { "version": "3.11.174", "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-3.11.174.tgz", diff --git a/package.json b/package.json index 1faf42f65b70..bfd035211038 100644 --- a/package.json +++ b/package.json @@ -124,7 +124,6 @@ "lottie-react-native": "6.5.1", "mapbox-gl": "^2.15.0", "onfido-sdk-ui": "14.15.0", - "pdf-lib": "^1.17.1", "process": "^0.11.10", "pusher-js": "8.3.0", "react": "18.2.0", diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx index 7a4f7d08ca34..639dc52ad585 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx @@ -23,7 +23,6 @@ import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import * as FileUtils from '@libs/fileDownload/FileUtils'; import getCurrentPosition from '@libs/getCurrentPosition'; -import isPdfFilePasswordProtected from '@libs/isPdfFilePasswordProtected'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; From 92d0704abddb13c27abf52dc01f161b359a99b65 Mon Sep 17 00:00:00 2001 From: tienifr Date: Sat, 8 Jun 2024 17:02:44 +0700 Subject: [PATCH 15/19] fix lint --- src/libs/isPdfFilePasswordProtected/index.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libs/isPdfFilePasswordProtected/index.tsx b/src/libs/isPdfFilePasswordProtected/index.tsx index 12112b4fa6e9..bd6c9af8970a 100644 --- a/src/libs/isPdfFilePasswordProtected/index.tsx +++ b/src/libs/isPdfFilePasswordProtected/index.tsx @@ -1,4 +1,4 @@ -import * as pdfjsLib from 'pdfjs-dist/build/pdf'; +import * as pdfjsLib from 'pdfjs-dist'; const isPdfFilePasswordProtected = (file) => { return new Promise((resolve, reject) => { @@ -6,6 +6,10 @@ const isPdfFilePasswordProtected = (file) => { reader.onload = async (event) => { const arrayBuffer = event.target?.result; + if (!arrayBuffer) { + resolve(false); + return; + } try { const loadingTask = pdfjsLib.getDocument({data: arrayBuffer}); @@ -14,7 +18,6 @@ const isPdfFilePasswordProtected = (file) => { resolve(false); }, (error) => { - console.log('***********', error); if (error.name === 'PasswordException') { resolve(true); } else { From 6115929b6179f44ffd780c9e8a4677d88d68d472 Mon Sep 17 00:00:00 2001 From: tienifr Date: Sat, 8 Jun 2024 17:16:48 +0700 Subject: [PATCH 16/19] fix lint --- src/libs/isPdfFilePasswordProtected/index.tsx | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/libs/isPdfFilePasswordProtected/index.tsx b/src/libs/isPdfFilePasswordProtected/index.tsx index bd6c9af8970a..8cd91de1ff95 100644 --- a/src/libs/isPdfFilePasswordProtected/index.tsx +++ b/src/libs/isPdfFilePasswordProtected/index.tsx @@ -1,37 +1,37 @@ import * as pdfjsLib from 'pdfjs-dist'; +import type {FileObject} from '@components/AttachmentModal'; -const isPdfFilePasswordProtected = (file) => { - return new Promise((resolve, reject) => { +const isPdfFilePasswordProtected = (file: FileObject): Promise => { + return new Promise((resolve) => { const reader = new FileReader(); - reader.onload = async (event) => { + reader.onload = (event) => { const arrayBuffer = event.target?.result; if (!arrayBuffer) { resolve(false); - return; - } - - try { - const loadingTask = pdfjsLib.getDocument({data: arrayBuffer}); - loadingTask.promise.then( - () => { - resolve(false); - }, - (error) => { - if (error.name === 'PasswordException') { - resolve(true); - } else { - reject(error); - } - }, - ); - } catch (error) { - reject(error); + } else { + try { + const loadingTask = pdfjsLib.getDocument({data: arrayBuffer}); + loadingTask.promise.then( + () => { + resolve(false); + }, + (error) => { + if (error.name === 'PasswordException') { + resolve(true); + } else { + resolve(false); + } + }, + ); + } catch (error) { + resolve(false); + } } }; reader.onerror = (error) => { - reject(error); + resolve(false); }; reader.readAsArrayBuffer(file); From 166b3b2a7cb159a9e85cba6fecabefed338176b0 Mon Sep 17 00:00:00 2001 From: tienifr Date: Sat, 8 Jun 2024 17:25:21 +0700 Subject: [PATCH 17/19] fix typecheck --- src/libs/isPdfFilePasswordProtected/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/isPdfFilePasswordProtected/index.tsx b/src/libs/isPdfFilePasswordProtected/index.tsx index 8cd91de1ff95..3f4822de307a 100644 --- a/src/libs/isPdfFilePasswordProtected/index.tsx +++ b/src/libs/isPdfFilePasswordProtected/index.tsx @@ -34,7 +34,7 @@ const isPdfFilePasswordProtected = (file: FileObject): Promise => { resolve(false); }; - reader.readAsArrayBuffer(file); + reader.readAsArrayBuffer(file as Blob); }); }; From 41b00c950290a5fc590cf70416f34cae8177a92b Mon Sep 17 00:00:00 2001 From: tienifr Date: Sat, 8 Jun 2024 17:37:14 +0700 Subject: [PATCH 18/19] fix lint --- src/libs/isPdfFilePasswordProtected/index.tsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/libs/isPdfFilePasswordProtected/index.tsx b/src/libs/isPdfFilePasswordProtected/index.tsx index 3f4822de307a..59d1f67eed04 100644 --- a/src/libs/isPdfFilePasswordProtected/index.tsx +++ b/src/libs/isPdfFilePasswordProtected/index.tsx @@ -1,8 +1,8 @@ import * as pdfjsLib from 'pdfjs-dist'; import type {FileObject} from '@components/AttachmentModal'; -const isPdfFilePasswordProtected = (file: FileObject): Promise => { - return new Promise((resolve) => { +const isPdfFilePasswordProtected = (file: FileObject): Promise => + new Promise((resolve) => { const reader = new FileReader(); reader.onload = (event) => { @@ -30,12 +30,10 @@ const isPdfFilePasswordProtected = (file: FileObject): Promise => { } }; - reader.onerror = (error) => { + reader.onerror = () => { resolve(false); }; reader.readAsArrayBuffer(file as Blob); }); -}; - export default isPdfFilePasswordProtected; From 61666db4e1ff745bc1fca790c948101a73e99351 Mon Sep 17 00:00:00 2001 From: tienifr Date: Mon, 17 Jun 2024 14:53:05 +0700 Subject: [PATCH 19/19] fix comment --- src/libs/isPdfFilePasswordProtected/index.tsx | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/libs/isPdfFilePasswordProtected/index.tsx b/src/libs/isPdfFilePasswordProtected/index.tsx index 59d1f67eed04..19ce44b9b8e3 100644 --- a/src/libs/isPdfFilePasswordProtected/index.tsx +++ b/src/libs/isPdfFilePasswordProtected/index.tsx @@ -9,24 +9,24 @@ const isPdfFilePasswordProtected = (file: FileObject): Promise => const arrayBuffer = event.target?.result; if (!arrayBuffer) { resolve(false); - } else { - try { - const loadingTask = pdfjsLib.getDocument({data: arrayBuffer}); - loadingTask.promise.then( - () => { - resolve(false); - }, - (error) => { - if (error.name === 'PasswordException') { - resolve(true); - } else { - resolve(false); - } - }, - ); - } catch (error) { - resolve(false); - } + return; + } + try { + const loadingTask = pdfjsLib.getDocument({data: arrayBuffer}); + loadingTask.promise.then( + () => { + resolve(false); + }, + (error) => { + if (error.name === 'PasswordException') { + resolve(true); + return; + } + resolve(false); + }, + ); + } catch (error) { + resolve(false); } };