From 336d048c03a983a79c5c723c1ec5e060ff8aa6ab Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Tue, 19 Sep 2023 17:31:02 +0200 Subject: [PATCH 1/4] [TS migration] Migrate 'ReceiptUtils.js' lib to TypeScript --- src/CONST.ts | 4 +++ src/libs/{ReceiptUtils.js => ReceiptUtils.ts} | 30 +++++++++++-------- 2 files changed, 22 insertions(+), 12 deletions(-) rename src/libs/{ReceiptUtils.js => ReceiptUtils.ts} (67%) diff --git a/src/CONST.ts b/src/CONST.ts index dd192f1b257c..838af5dad4e6 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -45,6 +45,10 @@ const CONST = { ARROW_HIDE_DELAY: 3000, API_ATTACHMENT_VALIDATIONS: { + // This is a list of file extensions that are not allowed to be uploaded to the server. + // TODO: This list should be updated to include all file types that are not allowed to be uploaded to the server. + UNALLOWED_EXTENSIONS: [''], + // 24 megabytes in bytes, this is limit set on servers, do not update without wider internal discussion MAX_SIZE: 25165824, diff --git a/src/libs/ReceiptUtils.js b/src/libs/ReceiptUtils.ts similarity index 67% rename from src/libs/ReceiptUtils.js rename to src/libs/ReceiptUtils.ts index d90a6cbf0e37..9e0ded5ccc0c 100644 --- a/src/libs/ReceiptUtils.js +++ b/src/libs/ReceiptUtils.ts @@ -1,6 +1,5 @@ -import lodashGet from 'lodash/get'; -import _ from 'underscore'; import Str from 'expensify-common/lib/str'; +import {ImageSourcePropType} from 'react-native'; import * as FileUtils from './fileDownload/FileUtils'; import CONST from '../CONST'; import Receipt from './actions/Receipt'; @@ -9,19 +8,21 @@ import ReceiptDoc from '../../assets/images/receipt-doc.png'; import ReceiptGeneric from '../../assets/images/receipt-generic.png'; import ReceiptSVG from '../../assets/images/receipt-svg.png'; -function validateReceipt(file) { - const {fileExtension} = FileUtils.splitExtensionFromFileName(lodashGet(file, 'name', '')); - if (_.contains(CONST.API_ATTACHMENT_VALIDATIONS.UNALLOWED_EXTENSIONS, fileExtension.toLowerCase())) { +function validateReceipt(file: File): boolean { + const {fileExtension} = FileUtils.splitExtensionFromFileName(file?.name ?? '') as {fileExtension: string}; + + if ((CONST.API_ATTACHMENT_VALIDATIONS.UNALLOWED_EXTENSIONS as readonly string[]).includes(fileExtension.toLowerCase())) { Receipt.setUploadReceiptError(true, 'attachmentPicker.wrongFileType', 'attachmentPicker.notAllowedExtension'); return false; } - if (lodashGet(file, 'size', 0) > CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE) { + const fileSize = file?.size ?? 0; + if (fileSize > CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE) { Receipt.setUploadReceiptError(true, 'attachmentPicker.attachmentTooLarge', 'attachmentPicker.sizeExceeded'); return false; } - if (lodashGet(file, 'size', 0) < CONST.API_ATTACHMENT_VALIDATIONS.MIN_SIZE) { + if (fileSize < CONST.API_ATTACHMENT_VALIDATIONS.MIN_SIZE) { Receipt.setUploadReceiptError(true, 'attachmentPicker.attachmentTooSmall', 'attachmentPicker.sizeNotMet'); return false; } @@ -29,14 +30,18 @@ function validateReceipt(file) { return true; } +type ThumbnailAndImageURI = { + thumbnail: string | null; + image: ImageSourcePropType | string; +}; + /** * Grab the appropriate receipt image and thumbnail URIs based on file type * - * @param {String} path URI to image, i.e. blob:new.expensify.com/9ef3a018-4067-47c6-b29f-5f1bd35f213d or expensify.com/receipts/w_e616108497ef940b7210ec6beb5a462d01a878f4.jpg - * @param {String} filename of uploaded image or last part of remote URI - * @returns {Object} + * @param path URI to image, i.e. blob:new.expensify.com/9ef3a018-4067-47c6-b29f-5f1bd35f213d or expensify.com/receipts/w_e616108497ef940b7210ec6beb5a462d01a878f4.jpg + * @param filename of uploaded image or last part of remote URI */ -function getThumbnailAndImageURIs(path, filename) { +function getThumbnailAndImageURIs(path: string, filename: string): ThumbnailAndImageURI { const isReceiptImage = Str.isImage(filename); // For local files, we won't have a thumbnail yet @@ -48,7 +53,7 @@ function getThumbnailAndImageURIs(path, filename) { return {thumbnail: `${path}.1024.jpg`, image: path}; } - const {fileExtension} = FileUtils.splitExtensionFromFileName(filename); + const {fileExtension} = FileUtils.splitExtensionFromFileName(filename) as {fileExtension?: string}; let image = ReceiptGeneric; if (fileExtension === CONST.IOU.FILE_TYPES.HTML) { image = ReceiptHTML; @@ -61,6 +66,7 @@ function getThumbnailAndImageURIs(path, filename) { if (fileExtension === CONST.IOU.FILE_TYPES.SVG) { image = ReceiptSVG; } + return {thumbnail: null, image}; } From 4ec2fdd27b0d6cf2820ec91aa40c8009432047e7 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Wed, 20 Sep 2023 07:35:35 +0200 Subject: [PATCH 2/4] Remove unallowed extension check --- src/CONST.ts | 4 ---- src/libs/ReceiptUtils.ts | 7 ------- 2 files changed, 11 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index 838af5dad4e6..dd192f1b257c 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -45,10 +45,6 @@ const CONST = { ARROW_HIDE_DELAY: 3000, API_ATTACHMENT_VALIDATIONS: { - // This is a list of file extensions that are not allowed to be uploaded to the server. - // TODO: This list should be updated to include all file types that are not allowed to be uploaded to the server. - UNALLOWED_EXTENSIONS: [''], - // 24 megabytes in bytes, this is limit set on servers, do not update without wider internal discussion MAX_SIZE: 25165824, diff --git a/src/libs/ReceiptUtils.ts b/src/libs/ReceiptUtils.ts index 9e0ded5ccc0c..9e659faf1f3c 100644 --- a/src/libs/ReceiptUtils.ts +++ b/src/libs/ReceiptUtils.ts @@ -9,13 +9,6 @@ import ReceiptGeneric from '../../assets/images/receipt-generic.png'; import ReceiptSVG from '../../assets/images/receipt-svg.png'; function validateReceipt(file: File): boolean { - const {fileExtension} = FileUtils.splitExtensionFromFileName(file?.name ?? '') as {fileExtension: string}; - - if ((CONST.API_ATTACHMENT_VALIDATIONS.UNALLOWED_EXTENSIONS as readonly string[]).includes(fileExtension.toLowerCase())) { - Receipt.setUploadReceiptError(true, 'attachmentPicker.wrongFileType', 'attachmentPicker.notAllowedExtension'); - return false; - } - const fileSize = file?.size ?? 0; if (fileSize > CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE) { Receipt.setUploadReceiptError(true, 'attachmentPicker.attachmentTooLarge', 'attachmentPicker.sizeExceeded'); From 610da861891a487544b8b0c3fba4980e1a011c06 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Wed, 20 Sep 2023 15:43:56 +0200 Subject: [PATCH 3/4] Rerun tests --- src/libs/ReceiptUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/ReceiptUtils.ts b/src/libs/ReceiptUtils.ts index 8d46485fd606..b159e49ec8b8 100644 --- a/src/libs/ReceiptUtils.ts +++ b/src/libs/ReceiptUtils.ts @@ -8,8 +8,8 @@ import ReceiptGeneric from '../../assets/images/receipt-generic.png'; import ReceiptSVG from '../../assets/images/receipt-svg.png'; type ThumbnailAndImageURI = { - thumbnail: string | null; image: ImageSourcePropType | string; + thumbnail: string | null; }; /** From 5fa86e979de000d6a3284fdd9682a8fbd73b5bbd Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Tue, 26 Sep 2023 09:40:29 +0200 Subject: [PATCH 4/4] Extract type --- src/libs/ReceiptUtils.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libs/ReceiptUtils.ts b/src/libs/ReceiptUtils.ts index b159e49ec8b8..cdc45cb119d5 100644 --- a/src/libs/ReceiptUtils.ts +++ b/src/libs/ReceiptUtils.ts @@ -12,6 +12,11 @@ type ThumbnailAndImageURI = { thumbnail: string | null; }; +type FileNameAndExtension = { + fileExtension?: string; + fileName?: string; +}; + /** * Grab the appropriate receipt image and thumbnail URIs based on file type * @@ -30,7 +35,7 @@ function getThumbnailAndImageURIs(path: string, filename: string): ThumbnailAndI return {thumbnail: `${path}.1024.jpg`, image: path}; } - const {fileExtension} = FileUtils.splitExtensionFromFileName(filename) as {fileExtension?: string}; + const {fileExtension} = FileUtils.splitExtensionFromFileName(filename) as FileNameAndExtension; let image = ReceiptGeneric; if (fileExtension === CONST.IOU.FILE_TYPES.HTML) { image = ReceiptHTML;