Skip to content

feat: support .md and .mdx file uploads#8995

Open
sriramveeraghanta wants to merge 2 commits into
previewfrom
feat/file-uploads-md-mdx-support
Open

feat: support .md and .mdx file uploads#8995
sriramveeraghanta wants to merge 2 commits into
previewfrom
feat/file-uploads-md-mdx-support

Conversation

@sriramveeraghanta
Copy link
Copy Markdown
Member

@sriramveeraghanta sriramveeraghanta commented May 2, 2026

Summary

  • Allow .md and .mdx files to flow through the existing attachment upload pipeline.
  • Plain-text formats have no magic bytes, so signature-based MIME detection returned an empty type and the backend rejected the upload — added an extension-based fallback.
  • Backend allow-list now includes text/mdx (text/markdown was already present); removed a duplicate text/markdown entry.
  • Editor accept list adds text/mdx; attachment icon picker handles md/markdown/mdx.

Changes

  • packages/services/src/file/helper.ts — fallback to text/markdown / text/mdx from extension when file-type signature detection yields nothing.
  • packages/editor/src/core/constants/config.ts — add text/mdx to ACCEPTED_ATTACHMENT_MIME_TYPES.
  • apps/api/plane/settings/common.py — add text/mdx to ATTACHMENT_MIME_TYPES; drop duplicate text/markdown.
  • apps/web/core/components/icons/attachment/attachment-icon.tsx — render TxtIcon for md/markdown/mdx.

Notes

MDX has no IANA-registered MIME type; text/mdx is a de-facto convention. Open to aliasing .mdx to text/markdown instead if preferred — that would avoid the backend allow-list change.

Test plan

  • Upload a .md file as an issue attachment — succeeds; correct icon is shown.
  • Upload an .mdx file as an issue attachment — succeeds; correct icon is shown.
  • Drag-and-drop .md/.mdx into the rich-text editor as an attachment — accepted.
  • Files containing dangerous double extensions (foo.exe.md) are still rejected.
  • Files outside the allow-list (e.g. .bin) are still rejected with the existing error.

Summary by CodeRabbit

  • New Features

    • Added support for MDX file attachments and acceptance of the MDX MIME type.
    • Improved MIME detection by falling back to file-extension derivation for text markup formats (e.g., markdown, MDX).
  • Bug Fixes

    • File type-to-icon mapping is now case-insensitive and treats MDX/markdown like other text files.
    • Invalid filenames now trigger a validation warning and are treated as unsupported.

Plain-text files have no magic bytes, so the file-type signature
detector returned an empty MIME type and the backend rejected them.
Add an extension-based fallback for markdown/mdx, allow text/mdx in
the API and editor allow-lists, and pick a file icon for these
extensions.
Copilot AI review requested due to automatic review settings May 2, 2026 18:31
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 2, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4f1697a9-c39d-488d-82be-4c592eecc7e8

📥 Commits

Reviewing files that changed from the base of the PR and between 86c6b69 and b374796.

📒 Files selected for processing (2)
  • apps/web/core/components/icons/attachment/attachment-icon.tsx
  • packages/services/src/file/helper.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/services/src/file/helper.ts
  • apps/web/core/components/icons/attachment/attachment-icon.tsx

📝 Walkthrough

Walkthrough

Adds MDX support across the stack by allowing the "text/mdx" MIME type, adding extension-based MIME detection for plain-text formats, and mapping markdown/MDX extensions to the text attachment icon. (48 words)

Changes

MDX support and extension-based detection

Layer / File(s) Summary
Attachment MIME allowlists
apps/api/plane/settings/common.py, packages/editor/src/core/constants/config.ts
Added "text/mdx" to ATTACHMENT_MIME_TYPES and ACCEPTED_ATTACHMENT_MIME_TYPES.
Icon mapping (UI)
apps/web/core/components/icons/attachment/attachment-icon.tsx
Made getFileIcon case-insensitive (fileType.toLowerCase()), and added "md", "markdown", and "mdx" cases to render the TxtIcon.
Extension → MIME detection
packages/services/src/file/helper.ts
Added EXTENSION_MIME_TYPE_MAP and detectMimeTypeFromExtension(filename) to map .md, .markdown, .mdx to MIME types; updated validateAndDetectFileType() to return early on invalid filenames and to fall back to extension-derived MIME when signature detection yields no type.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

I nibble bytes where codelines play,
MDX now hops into the day.
Extensions found, the icon snug,
MIME lined up — a cozy hug. 🐇✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The PR description is comprehensive with a detailed summary, specific file changes, implementation notes, and a complete test plan, but does not follow the repository's required template structure (Description, Type of Change, Screenshots, Test Scenarios, References). Reorganize the description to match the repository template: move 'Summary' into 'Description' section, select 'Feature' in Type of Change, add Screenshots/Media section if applicable, and reformat 'Test plan' to match the expected 'Test Scenarios' section.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'feat: support .md and .mdx file uploads' clearly and specifically describes the primary change — enabling upload support for markdown and MDX files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/file-uploads-md-mdx-support

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/services/src/file/helper.ts (1)

112-135: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Do not fall back to the extension after filename validation fails.

validateFilename() already flags suspicious names such as foo.exe.md, but the result is only logged. With the new extension fallback, those files still resolve to text/markdown / text/mdx and can pass the allow-list, which defeats the double-extension safeguard.

Suggested fix
 const validateAndDetectFileType = async (file: File): Promise<string> => {
   // Basic filename validation
   const filenameError = validateFilename(file.name);
   if (filenameError) {
     console.warn(`File validation warning: ${filenameError}`);
+    return "";
   }
 
   try {
     const signatureType = await detectMimeTypeFromSignature(file);
     if (signatureType) {
       return signatureType;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/services/src/file/helper.ts` around lines 112 - 135, If
validateFilename(file.name) returns an error, stop and do not use the extension
fallback; in validateAndDetectFileType, after calling validateFilename use the
returned filenameError to short-circuit and return an empty string (or otherwise
mark the file as unknown/rejected) instead of continuing to
detectMimeTypeFromExtension. Keep the existing signature-based detection path
(detectMimeTypeFromSignature) but only run it when validateFilename passed;
reference validateAndDetectFileType, validateFilename,
detectMimeTypeFromSignature, and detectMimeTypeFromExtension when making this
change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@packages/services/src/file/helper.ts`:
- Around line 112-135: If validateFilename(file.name) returns an error, stop and
do not use the extension fallback; in validateAndDetectFileType, after calling
validateFilename use the returned filenameError to short-circuit and return an
empty string (or otherwise mark the file as unknown/rejected) instead of
continuing to detectMimeTypeFromExtension. Keep the existing signature-based
detection path (detectMimeTypeFromSignature) but only run it when
validateFilename passed; reference validateAndDetectFileType, validateFilename,
detectMimeTypeFromSignature, and detectMimeTypeFromExtension when making this
change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ba97d0e1-9b14-4903-9ecf-89c664a15ef5

📥 Commits

Reviewing files that changed from the base of the PR and between a62fe8a and 86c6b69.

📒 Files selected for processing (4)
  • apps/api/plane/settings/common.py
  • apps/web/core/components/icons/attachment/attachment-icon.tsx
  • packages/editor/src/core/constants/config.ts
  • packages/services/src/file/helper.ts

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends Plane’s attachment upload flow to recognize Markdown and MDX files end-to-end by adding extension-based MIME fallback in the shared upload helper, allowing text/mdx through the editor/API allow-lists, and showing text-file icons for markdown attachments.

Changes:

  • Added extension-based MIME detection for plain-text uploads (.md, .markdown, .mdx) when signature detection returns no type.
  • Updated frontend and backend attachment MIME allow-lists to include MDX support.
  • Mapped markdown-family file extensions to the existing text attachment icon.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
packages/services/src/file/helper.ts Adds filename-extension fallback for markdown MIME detection in the shared upload metadata helper.
packages/editor/src/core/constants/config.ts Adds text/mdx to the editor attachment MIME allow-list.
apps/web/core/components/icons/attachment/attachment-icon.tsx Routes md / markdown / mdx extensions to the text-file icon.
apps/api/plane/settings/common.py Adds text/mdx to the backend attachment MIME allow-list and removes a duplicate markdown entry.

Comment on lines +128 to 134
// Plain-text formats (markdown, mdx, …) have no magic bytes — fall back to extension.
const extensionType = detectMimeTypeFromExtension(file.name);
if (extensionType) {
return extensionType;
}

// fallback for unknown files
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
"text/plain",
"text/markdown",
"text/mdx",
Comment on lines +50 to +52
case "md":
case "markdown":
case "mdx":
- Short-circuit validateAndDetectFileType when validateFilename flags a
  suspicious name so files like foo.exe.md cannot bypass the attachment
  allowlist via the new extension MIME fallback.
- Lowercase fileType in getFileIcon so uppercase extensions (e.g. .MD,
  .PDF) resolve to the correct icon.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants