fix(api): accept MIME types with parameters or whitespace (CS-217)#2576
Merged
fix(api): accept MIME types with parameters or whitespace (CS-217)#2576
Conversation
File upload endpoints were rejecting valid Content-Type values like `application/pdf;charset=utf-8` or `application/pdf\n` with a 400 "Invalid MIME type format" error, because each DTO enforced the regex /^[a-zA-Z0-9\-]+\/[a-zA-Z0-9\-\+\.]+$/ with no trim or parameter strip. Extracts a shared `IsMimeTypeField` decorator (+ `normalizeMimeType` helper) that: - strips RFC 7231 media-type parameters (`;charset=...`) and whitespace - lowercases the value before validation and persistence - matches the RFC 6838 restricted-name-chars grammar Applied to all four upload DTOs: - attachments/upload-attachment.dto.ts - tasks/dto/upload-attachment.dto.ts - task-management/dto/upload-task-item-attachment.dto.ts - org-chart/dto/upload-org-chart.dto.ts Also removes dead `BLOCKED_MIME_TYPES` constants from two DTOs — the actual blocklist lives in `attachments.service.ts` and operates on the already-lowercased fileType. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
No issues found across 6 files
Auto-approved: Fixes MIME type validation bug (CS-217) by normalizing inputs. Low risk, high test coverage (18 unit tests), and cleans up redundant DTO code.
Linked issue analysis
Linked issue: CS-217: Invalid MIME type format error in API
| Status | Acceptance criteria | Notes |
|---|---|---|
| ✅ | Strip RFC 7231 media-type parameters and whitespace before validation (accept application/pdf;charset=utf-8 and trailing whitespace) | normalizeMimeType strips parameters/whitespace; decorator transforms value |
| ✅ | Lowercase the value before validation | normalizeMimeType lowercases the value |
| ✅ | Validate against the RFC 6838 restricted-name-chars grammar | MIME_TYPE_REGEX implements restricted-name-chars grammar |
| ✅ | Add shared IsMimeTypeField decorator and normalizeMimeType helper in apps/api/src/utils/mime-type.validator.ts | New file exports IsMimeTypeField and normalizeMimeType |
| ✅ | Apply the new decorator to four DTOs (attachments, tasks/dto, task-management/dto, org-chart/dto) | DTOs now import and use @IsMimeTypeField() for fileType |
| ✅ | Remove duplicated inline regex from those DTOs | Inline @matches regex removed from the DTOs |
| ✅ | Remove dead BLOCKED_MIME_TYPES constants from two DTOs (attachments and tasks) | BLOCKED_MIME_TYPES arrays deleted from DTO files |
| ❌ | Ensure blocklist enforcement remains in attachments.service.ts and operates on the lowercased value | No changes or references to attachments.service.ts in diffs |
| ✅ | Add unit tests covering regressions and negative cases (18 tests) | mime-type.validator.spec.ts with the described test cases was added |
| ❌ | Full API typecheck: no new errors on changed files | No CI/typecheck output or artifacts included in diffs |
| ❌ | Manual: re-run customer's failing upload (application/pdf;charset=utf-8) against staging — should succeed | No evidence of manual staging test or results in the PR |
| ❌ | Manual: attempt to upload application/javascript;charset=utf-8 — should still be rejected by attachments.service.ts blocklist | No tests or code changes shown that exercise attachments.service.ts blocklist |
| ✅ | Keep validation message 'Invalid MIME type format' for consistency | Matches(...) retains message 'Invalid MIME type format' in validator |
| ✅ | No schema changes or DB fields | Changed files are DTOs and utils; no DB/schema files modified |
Contributor
|
🎉 This PR is included in version 3.23.2 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes CS-217 — customer file upload endpoints returning
400 Invalid MIME type formatfor legitimateapplication/pdfandapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheetvalues.Root cause: Four DTOs (
attachments,tasks/dto,task-management/dto,org-chart/dto) each declared@Matches(/^[a-zA-Z0-9\-]+\/[a-zA-Z0-9\-\+\.]+$/)with no trim or parameter strip. So the regex itself accepts bareapplication/pdf, but the customer's HTTP client is almost certainly sending the Content-Type with a parameter (e.g.application/pdf;charset=utf-8) or trailing whitespace/newline, which the regex rejects.Fix: Extracted a shared
IsMimeTypeFielddecorator +normalizeMimeTypehelper inapps/api/src/utils/mime-type.validator.ts. It:;...) and whitespace before validationrestricted-name-charsgrammarApplied the new decorator to all four DTOs and removed the now-duplicated inline regex. Also removed dead
BLOCKED_MIME_TYPESconstants from two DTOs — the real enforcement lives inattachments.service.tsand always operated on the lowercased value.Test plan
mime-type.validator.spec.tscover:application/pdf,application/pdf;charset=utf-8, the full xlsx vendor type, trailing whitespace/newline, uppercase,application/vnd.api+json,image/svg+xmlcd apps/api && npx jest src/utils/mime-type.validator→ 18/18 passapplication/pdf;charset=utf-8) against staging — should succeedapplication/javascript;charset=utf-8— should still be rejected byattachments.service.tsblocklistNotes
@IsInallow-list with it). So the "worked previously" timeframe predates the regex; likely the customer's HTTP client changed recently and began including;charset=...parameters in thefileTypefield.🤖 Generated with Claude Code
Summary by cubic
Fixes CS-217 by accepting MIME types with parameters or whitespace in file upload requests. Adds a shared
IsMimeTypeFieldvalidator to normalize and validate values, preventing 400s for legitimate types likeapplication/pdf;charset=utf-8.IsMimeTypeFieldwithnormalizeMimeTypeto strip parameters/whitespace, lowercase, and validate per RFC 6838.BLOCKED_MIME_TYPESconstants (blocklist stays inattachments.service.ts).application/pdf, vendor xlsx type,+json, case/whitespace) and invalid inputs.Written for commit 911a790. Summary will update on new commits.