Skip to content

fix(upgrade): normalize image/jpg → image/jpeg for ID document upload (ENG-291)#607

Merged
Nodirbek75 merged 4 commits intomainfrom
fix/eng-291-id-document-content-type
Apr 6, 2026
Merged

fix(upgrade): normalize image/jpg → image/jpeg for ID document upload (ENG-291)#607
Nodirbek75 merged 4 commits intomainfrom
fix/eng-291-id-document-content-type

Conversation

@patoo0x
Copy link
Copy Markdown
Contributor

@patoo0x patoo0x commented Apr 5, 2026

Root Cause (ENG-291)

HTTP 400 on account upgrade Step 4 (ID document upload) — Android v0.5.0.70.

The bug: Android's react-native-image-picker and Vision Camera return 'image/jpg' for some JPEG photos. The backend storage service only accepts ['image/jpeg', 'image/png', 'image/webp']. 'image/jpg' is not in the backend allowlist → InvalidFileTypeError → no upload URL generated → HTTP 400 on form submission.

The 400 comes from the Flash backend — specifically the idDocumentUploadUrlGenerate mutation, before any ERPNext interaction.

Fix

New shared utility app/utils/image-content-type.ts:

  • normalizeContentType(type) — maps 'image/jpg''image/jpeg', passes others through
  • isValidContentType(type) — checks against backend-compatible allowlist

Applied in:

  • useAccountUpgrade.tsx — normalizes before calling upload URL mutation AND before the S3 PUT
  • PhotoUploadField.tsx — normalizes in both gallery picker and camera paths; fallback to 'image/jpeg' if camera blob.type is empty string

Testing

Unit tests written in __tests__/hooks/use-account-upgrade-content-type.spec.ts. Test infra has a pre-existing ttypescript/Node25 incompatibility — tests will run when that's resolved. Manual verification: upload a photo taken with camera on Android and confirm step 4 completes successfully.

Note for reviewers

The client-side ALLOWED_FILE_TYPES array in PhotoUploadField.tsx was ['image/jpeg', 'image/png', 'image/jpg'] — it included image/jpg but the backend didn't. This mismatch let through a type the backend would always reject. Now using the shared utility that matches backend behavior exactly.

patoo0x and others added 2 commits March 31, 2026 18:05
closing #527

- Add zero-balance check to ConversionAmountError before amount-exceed check
- Show red error immediately when fromWallet has no balance
- Add emptyWallet i18n key to ConversionDetailsScreen for localization
… (ENG-291)

Root cause: Android react-native-image-picker and Vision Camera return
'image/jpg' for some JPEG photos. The backend storage service only accepts
['image/jpeg', 'image/png', 'image/webp'] — 'image/jpg' causes
InvalidFileTypeError → no upload URL generated → HTTP 400 on step 4.

Changes:
- app/utils/image-content-type.ts (new): shared normalizeContentType()
  and isValidContentType() utilities matching backend allowlist
- app/hooks/useAccountUpgrade.tsx: normalize contentType before calling
  idDocumentUploadUrlGenerate and uploadFileToS3
- app/components/account-upgrade-flow/PhotoUploadField.tsx:
  - remove ALLOWED_FILE_TYPES (was out of sync with backend)
  - use normalizeContentType + isValidContentType from shared util
  - normalize before validating in both gallery and camera paths
  - fallback to 'image/jpeg' if camera blob.type is empty string
- __tests__/hooks/use-account-upgrade-content-type.spec.ts (new):
  unit tests for normalizeContentType and isValidContentType

Note: test infra (ttypescript + Node 25) has a pre-existing
incompatibility — tests are written and will run when that's resolved.

Fixes: ENG-291
@linear
Copy link
Copy Markdown

linear Bot commented Apr 5, 2026

@islandbitcoin islandbitcoin requested a review from Nodirbek75 April 5, 2026 21:49
@islandbitcoin islandbitcoin added the bug Something isn't working label Apr 5, 2026
forge0x and others added 2 commits April 5, 2026 19:38
accountNumber in GraphQL schema is now String (not Int).
Remove Number() conversion — pass the string value directly.
Paired with backend PR #319 (flash repo).
@Nodirbek75 Nodirbek75 merged commit baa75dc into main Apr 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants