diff --git a/src/CONST.ts b/src/CONST.ts index 29bb0b83aaee..3c93ecf6affb 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -50,6 +50,9 @@ const CONST = { // An arbitrary size, but the same minimum as in the PHP layer MIN_SIZE: 240, + + // 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: { diff --git a/src/pages/iou/ReceiptSelector/index.js b/src/pages/iou/ReceiptSelector/index.js index 672b1458bf8e..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.UNALLOWED_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 d47a2c7739a2..afcd546d4abf 100644 --- a/src/pages/iou/ReceiptSelector/index.native.js +++ b/src/pages/iou/ReceiptSelector/index.native.js @@ -103,6 +103,25 @@ function ReceiptSelector({route, report, iou, transactionID, isInTabNavigator, s }; }, []); + const validateReceipt = (file) => { + const {fileExtension} = FileUtils.splitExtensionFromFileName(lodashGet(file, 'name', '')); + if (!CONST.API_ATTACHMENT_VALIDATIONS.ALLOWED_RECEIPT_EXTENSIONS.includes(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 @@ -212,6 +231,9 @@ function ReceiptSelector({route, report, iou, transactionID, isInTabNavigator, s onPress={() => { openPicker({ onPicked: (file) => { + if (!validateReceipt(file)) { + return; + } const filePath = file.uri; IOU.setMoneyRequestReceipt(filePath, file.name);