From a984962532b4a969fdd83774f7a220fdbe30de66 Mon Sep 17 00:00:00 2001 From: Alberto Date: Thu, 19 Oct 2023 13:49:33 +0200 Subject: [PATCH 1/5] Check valid receipt files in frontend --- src/CONST.ts | 21 +++++++++++++++++++++ src/pages/iou/ReceiptSelector/index.js | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/CONST.ts b/src/CONST.ts index bc74cbe77717..a7680514d0fb 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -52,6 +52,27 @@ const CONST = { MIN_SIZE: 240, }, + API_RECEIPT_EXTENSIONS: [ + 'jpg', + 'jpeg', + 'gif', + 'png', + 'pdf', + 'htm', + 'html', + 'text', + 'rtf', + 'doc', + 'tif', + 'tiff', + 'msword', + 'zip', + 'xml', + 'message', + ], + + + AUTO_AUTH_STATE: { NOT_STARTED: 'not-started', SIGNING_IN: 'signing-in', diff --git a/src/pages/iou/ReceiptSelector/index.js b/src/pages/iou/ReceiptSelector/index.js index ca9fe90575e7..32f31ae5a1e7 100644 --- a/src/pages/iou/ReceiptSelector/index.js +++ b/src/pages/iou/ReceiptSelector/index.js @@ -103,7 +103,7 @@ function ReceiptSelector({route, transactionID, iou, report}) { function validateReceipt(file) { const {fileExtension} = FileUtils.splitExtensionFromFileName(lodashGet(file, 'name', '')); - if (_.contains(CONST.API_ATTACHMENT_VALIDATIONS.UNALLOWED_EXTENSIONS, fileExtension.toLowerCase())) { + if (!_.contains(CONST.API_RECEIPT_EXTENSIONS, fileExtension.toLowerCase())) { setUploadReceiptError(true, 'attachmentPicker.wrongFileType', 'attachmentPicker.notAllowedExtension'); return false; } From 1d7ad6d3e616677b9c1c8688dcaf7ff7b8123f7d Mon Sep 17 00:00:00 2001 From: Alberto Date: Thu, 19 Oct 2023 13:50:11 +0200 Subject: [PATCH 2/5] prettier --- src/CONST.ts | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index a7680514d0fb..60f11e46ac9e 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -52,26 +52,7 @@ const CONST = { MIN_SIZE: 240, }, - API_RECEIPT_EXTENSIONS: [ - 'jpg', - 'jpeg', - 'gif', - 'png', - 'pdf', - 'htm', - 'html', - 'text', - 'rtf', - 'doc', - 'tif', - 'tiff', - 'msword', - 'zip', - 'xml', - 'message', - ], - - + API_RECEIPT_EXTENSIONS: ['jpg', 'jpeg', 'gif', 'png', 'pdf', 'htm', 'html', 'text', 'rtf', 'doc', 'tif', 'tiff', 'msword', 'zip', 'xml', 'message'], AUTO_AUTH_STATE: { NOT_STARTED: 'not-started', From 27f38fa03709f3546278a0dad05ae939402a6efb Mon Sep 17 00:00:00 2001 From: Alberto Date: Thu, 19 Oct 2023 14:30:39 +0200 Subject: [PATCH 3/5] work in mobile too --- src/pages/iou/ReceiptSelector/index.native.js | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/pages/iou/ReceiptSelector/index.native.js b/src/pages/iou/ReceiptSelector/index.native.js index 8bf13422f70c..3d2af1ef7877 100644 --- a/src/pages/iou/ReceiptSelector/index.native.js +++ b/src/pages/iou/ReceiptSelector/index.native.js @@ -2,6 +2,7 @@ import {ActivityIndicator, Alert, AppState, Text, View} from 'react-native'; import React, {useCallback, useEffect, useRef, useState} from 'react'; import {useCameraDevices} from 'react-native-vision-camera'; import lodashGet from 'lodash/get'; +import _ from 'underscore'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; import {RESULTS} from 'react-native-permissions'; @@ -99,6 +100,25 @@ function ReceiptSelector({route, report, iou, transactionID, isInTabNavigator}) }; }, []); + const validateReceipt = (file) => { + const {fileExtension} = FileUtils.splitExtensionFromFileName(lodashGet(file, 'name', '')); + if (!_.contains(CONST.API_RECEIPT_EXTENSIONS, fileExtension.toLowerCase())) { + Alert.alert(translate('attachmentPicker.wrongFileType'), translate('attachmentPicker.notAllowedExtension')); + return false; + } + + if (lodashGet(file, 'size', 0) > CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE) { + Alert.alert(translate('attachmentPicker.attachmentTooLarge'), translate('attachmentPicker.sizeExceeded')); + return false; + } + + if (lodashGet(file, 'size', 0) < CONST.API_ATTACHMENT_VALIDATIONS.MIN_SIZE) { + Alert.alert(translate('attachmentPicker.attachmentTooSmall'), translate('attachmentPicker.sizeNotMet')); + return false; + } + return true; + }; + const askForPermissions = () => { // There's no way we can check for the BLOCKED status without requesting the permission first // https://github.com/zoontek/react-native-permissions/blob/a836e114ce3a180b2b23916292c79841a267d828/README.md?plain=1#L670 @@ -207,6 +227,9 @@ function ReceiptSelector({route, report, iou, transactionID, isInTabNavigator}) onPress={() => { openPicker({ onPicked: (file) => { + if (!validateReceipt(file)) { + return; + } const filePath = file.uri; IOU.setMoneyRequestReceipt(filePath, file.name); From 0f72486b1c8866b4fa8d00f638e98592a963d0e4 Mon Sep 17 00:00:00 2001 From: Alberto Date: Fri, 20 Oct 2023 13:06:06 +0200 Subject: [PATCH 4/5] rename const --- src/CONST.ts | 5 +++-- src/pages/iou/ReceiptSelector/index.js | 2 +- src/pages/iou/ReceiptSelector/index.native.js | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index 5bef9c038dcb..166a996d3aff 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -50,9 +50,10 @@ const CONST = { // An arbitrary size, but the same minimum as in the PHP layer MIN_SIZE: 240, - }, - API_RECEIPT_EXTENSIONS: ['jpg', 'jpeg', 'gif', 'png', 'pdf', 'htm', 'html', 'text', 'rtf', 'doc', 'tif', 'tiff', 'msword', 'zip', 'xml', 'message'], + // Allowed extensions for receipts + ALLOWED_RECEIPT_EXTENSIONS: ['jpg', 'jpeg', 'gif', 'png', 'pdf', 'htm', 'html', 'text', 'rtf', 'doc', 'tif', 'tiff', 'msword', 'zip', 'xml', 'message'], + }, AUTO_AUTH_STATE: { NOT_STARTED: 'not-started', diff --git a/src/pages/iou/ReceiptSelector/index.js b/src/pages/iou/ReceiptSelector/index.js index 32f31ae5a1e7..77fe99e63e12 100644 --- a/src/pages/iou/ReceiptSelector/index.js +++ b/src/pages/iou/ReceiptSelector/index.js @@ -103,7 +103,7 @@ function ReceiptSelector({route, transactionID, iou, report}) { function validateReceipt(file) { const {fileExtension} = FileUtils.splitExtensionFromFileName(lodashGet(file, 'name', '')); - if (!_.contains(CONST.API_RECEIPT_EXTENSIONS, fileExtension.toLowerCase())) { + if (!_.contains(CONST.API_ATTACHMENT_VALIDATIONS.ALLOWED_RECEIPT_EXTENSIONS, fileExtension.toLowerCase())) { setUploadReceiptError(true, 'attachmentPicker.wrongFileType', 'attachmentPicker.notAllowedExtension'); return false; } diff --git a/src/pages/iou/ReceiptSelector/index.native.js b/src/pages/iou/ReceiptSelector/index.native.js index 3d2af1ef7877..a16174471732 100644 --- a/src/pages/iou/ReceiptSelector/index.native.js +++ b/src/pages/iou/ReceiptSelector/index.native.js @@ -102,7 +102,7 @@ function ReceiptSelector({route, report, iou, transactionID, isInTabNavigator}) const validateReceipt = (file) => { const {fileExtension} = FileUtils.splitExtensionFromFileName(lodashGet(file, 'name', '')); - if (!_.contains(CONST.API_RECEIPT_EXTENSIONS, fileExtension.toLowerCase())) { + if (!_.contains(CONST.API_ATTACHMENT_VALIDATIONS.ALLOWED_RECEIPT_EXTENSIONS, fileExtension.toLowerCase())) { Alert.alert(translate('attachmentPicker.wrongFileType'), translate('attachmentPicker.notAllowedExtension')); return false; } From 0952ec214db3caef20b7b4cc72e2b5fb1de1a876 Mon Sep 17 00:00:00 2001 From: Alberto Date: Fri, 3 Nov 2023 13:11:19 +0100 Subject: [PATCH 5/5] avoid underscore --- src/pages/iou/ReceiptSelector/index.js | 3 +-- src/pages/iou/ReceiptSelector/index.native.js | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/pages/iou/ReceiptSelector/index.js b/src/pages/iou/ReceiptSelector/index.js index 7a594500d204..b6a15d69f02c 100644 --- a/src/pages/iou/ReceiptSelector/index.js +++ b/src/pages/iou/ReceiptSelector/index.js @@ -3,7 +3,6 @@ import PropTypes from 'prop-types'; import React, {useCallback, useContext, useReducer, useRef, useState} from 'react'; import {ActivityIndicator, PanResponder, PixelRatio, Text, View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; -import _ from 'underscore'; import Hand from '@assets/images/hand.svg'; import ReceiptUpload from '@assets/images/receipt-upload.svg'; import Shutter from '@assets/images/shutter.svg'; @@ -103,7 +102,7 @@ function ReceiptSelector({route, transactionID, iou, report}) { function validateReceipt(file) { const {fileExtension} = FileUtils.splitExtensionFromFileName(lodashGet(file, 'name', '')); - if (!_.contains(CONST.API_ATTACHMENT_VALIDATIONS.ALLOWED_RECEIPT_EXTENSIONS, fileExtension.toLowerCase())) { + if (!CONST.API_ATTACHMENT_VALIDATIONS.ALLOWED_RECEIPT_EXTENSIONS.includes(fileExtension.toLowerCase())) { setUploadReceiptError(true, 'attachmentPicker.wrongFileType', 'attachmentPicker.notAllowedExtension'); return false; } diff --git a/src/pages/iou/ReceiptSelector/index.native.js b/src/pages/iou/ReceiptSelector/index.native.js index 421fd0076abb..afcd546d4abf 100644 --- a/src/pages/iou/ReceiptSelector/index.native.js +++ b/src/pages/iou/ReceiptSelector/index.native.js @@ -1,5 +1,4 @@ import lodashGet from 'lodash/get'; -import _ from 'underscore'; import PropTypes from 'prop-types'; import React, {useCallback, useEffect, useRef, useState} from 'react'; import {ActivityIndicator, Alert, AppState, Text, View} from 'react-native'; @@ -106,7 +105,7 @@ function ReceiptSelector({route, report, iou, transactionID, isInTabNavigator, s const validateReceipt = (file) => { const {fileExtension} = FileUtils.splitExtensionFromFileName(lodashGet(file, 'name', '')); - if (!_.contains(CONST.API_ATTACHMENT_VALIDATIONS.ALLOWED_RECEIPT_EXTENSIONS, fileExtension.toLowerCase())) { + if (!CONST.API_ATTACHMENT_VALIDATIONS.ALLOWED_RECEIPT_EXTENSIONS.includes(fileExtension.toLowerCase())) { Alert.alert(translate('attachmentPicker.wrongFileType'), translate('attachmentPicker.notAllowedExtension')); return false; }