Skip to content

feat: enhance image upload validation across the application #22766

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 42 commits into
base: main
Choose a base branch
from

Conversation

Devanshusharma2005
Copy link
Contributor

@Devanshusharma2005 Devanshusharma2005 commented Jul 28, 2025

What does this PR do?

Enhancing Image upload validation.

  • Fixes #XXXX (GitHub issue number)
  • Fixes CAL-XXXX (Linear issue number - should be visible at the bottom of the GitHub issue description)

Visual Demo (For contributors especially)

A visual demonstration is strongly recommended, for both the original and new change (video / image - any one).

Video Demo (if applicable):

Screen.Recording.2025-07-28.170817.mp4

Mandatory Tasks (DO NOT REMOVE)

  • I have self-reviewed the code (A decent size PR without self-review might be rejected).
  • I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. If N/A, write N/A here and check the checkbox.
  • I confirm automated tests are in place that prove my fix is effective or that my feature works.

How should this be tested?

  • Are there environment variables that should be set?
  • What are the minimal test data to have?
  • What is expected (happy path) to have (input and output)?
  • Any other important info that could help to test that PR

Checklist

  • I haven't read the contributing guide
  • My code doesn't follow the style guidelines of this project
  • I haven't commented my code, particularly in hard-to-understand areas
  • I haven't checked if my changes generate no new warnings

@Devanshusharma2005 Devanshusharma2005 requested review from a team as code owners July 28, 2025 08:33
Copy link

vercel bot commented Jul 28, 2025

@Devanshusharma2005 is attempting to deploy a commit to the cal Team on Vercel.

A member of the Team first needs to authorize it.

@graphite-app graphite-app bot added the community Created by Linear-GitHub Sync label Jul 28, 2025
Copy link
Contributor

coderabbitai bot commented Jul 28, 2025

Walkthrough

Adds comprehensive image validation utilities and constants for client and server, plus client-side and server-side validators and tests. Integrates validation into avatar/logo/banner upload flows, OAuth profile photo handling, image uploader components (now async and with explicit MIME lists), and the avatar-serving route (validation plus security headers). Enhances error handling around image resizing and uploading and adds localization strings for validation errors.

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 9c4f036 and 9f480d0.

📒 Files selected for processing (1)
  • packages/trpc/server/routers/viewer/organizations/updateUser.handler.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/trpc/server/routers/viewer/organizations/updateUser.handler.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Install dependencies / Yarn install & cache
  • GitHub Check: Codacy Static Code Analysis
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@Devanshusharma2005 Devanshusharma2005 marked this pull request as draft July 28, 2025 08:33
@keithwillcode keithwillcode added the community-interns The team responsible for reviewing, testing and shipping low/medium community PRs label Jul 28, 2025
@dosubot dosubot bot added the ✨ feature New feature or request label Jul 28, 2025
Copy link

graphite-app bot commented Jul 28, 2025

Graphite Automations

"Add community label" took an action on this PR • (07/28/25)

1 label was added to this PR based on Keith Williams's automation.

Copy link
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.

Actionable comments posted: 3

♻️ Duplicate comments (2)
packages/trpc/server/routers/viewer/organizations/updateUser.handler.ts (1)

120-157: Remove redundant format validation after validateBase64Image

Same issue as in updateProfile.handler.ts - the base64 prefix check is redundant after validateBase64Image and creates a format support mismatch.

Apply the same fix to remove redundant validation:

   if (input.avatar) {
     // Comprehensive validation using magic numbers
     const validation = validateBase64Image(input.avatar);
     if (!validation.isValid) {
       throw new TRPCError({
         code: "BAD_REQUEST",
         message: `Invalid avatar image: ${validation.error}`,
       });
     }

-    // Additional check for supported base64 formats (after validation)
-    if (
-      input.avatar.startsWith("data:image/png;base64,") ||
-      input.avatar.startsWith("data:image/jpeg;base64,") ||
-      input.avatar.startsWith("data:image/jpg;base64,") ||
-      input.avatar.startsWith("data:image/svg+xml;base64,")
-    ) {
+    if (input.avatar === "") {
+      data.avatarUrl = null;
+    } else {
       try {
         const avatar = await resizeBase64Image(input.avatar);
         data.avatarUrl = await uploadAvatar({
           avatar,
           userId: user.id,
         });
       } catch (error) {
         throw new TRPCError({
           code: "BAD_REQUEST",
           message: error instanceof Error ? error.message : "Failed to upload avatar",
         });
       }
-    } else if (input.avatar === "") {
-      data.avatarUrl = null;
-    } else {
-      throw new TRPCError({
-        code: "BAD_REQUEST",
-        message: "Unsupported image format. Please use PNG, JPEG, or SVG.",
-      });
     }
   }
packages/ui/components/image-uploader/ImageUploader.tsx (1)

94-220: Extract duplicated validateImageFile function

This validation function is identical to the one in BannerUploader.tsx. Both components should share a common validation utility.

See the suggestion in BannerUploader.tsx review for extracting this to a shared utility file.

🧹 Nitpick comments (4)
packages/lib/server/imageValidation.ts (2)

123-132: Consider optimizing SVG content scanning for performance.

Converting the entire buffer to UTF-8 string for content scanning could be expensive for large SVG files. Consider scanning the first few KB or using a streaming approach for better performance.

-      const textContent = buffer.toString("utf8");
+      // Only scan first 10KB for dangerous patterns to improve performance
+      const scanLength = Math.min(buffer.length, 10 * 1024);
+      const textContent = buffer.subarray(0, scanLength).toString("utf8");

175-191: Simplify the JPEG format handling logic.

The function works correctly but has redundant logic in the JPEG validation section.

  // Handle JPEG variations
  if (
-    (detectedFormat === "jpeg" && (expectedFormat === "jpg" || expectedFormat === "jpeg")) ||
-    (expectedFormat === "jpeg" && detectedFormat === "jpeg")
+    (detectedFormat === "jpeg" && (expectedFormat === "jpg" || expectedFormat === "jpeg"))
  ) {
    return true;
  }

The second condition is redundant since expectedFormat === "jpeg" && detectedFormat === "jpeg" is already covered by the direct comparison on line 190.

packages/trpc/server/routers/viewer/organizations/update.handler.ts (2)

165-199: LGTM: Comprehensive banner validation and error handling

The banner validation implementation is thorough with proper TRPC error handling. The try-catch block ensures robust error handling during upload operations.

Consider removing the format checking after validation (lines 175-199) since validateBase64Image already validates the format. The current approach adds redundancy:

  if (input.banner) {
    // Validate the banner image data
    const validation = validateBase64Image(input.banner);
    if (!validation.isValid) {
      throw new TRPCError({
        code: "BAD_REQUEST",
        message: `Invalid banner image: ${validation.error}`,
      });
    }

-   if (
-     input.banner.startsWith("data:image/png;base64,") ||
-     input.banner.startsWith("data:image/jpeg;base64,") ||
-     input.banner.startsWith("data:image/jpg;base64,") ||
-     input.banner.startsWith("data:image/svg+xml;base64,")
-   ) {
      try {
        const banner = await resizeBase64Image(input.banner, { maxSize: 1500 });
        data.bannerUrl = await uploadLogo({
          logo: banner,
          teamId: currentOrgId,
          isBanner: true,
        });
      } catch (error) {
        throw new TRPCError({
          code: "BAD_REQUEST",
          message: error instanceof Error ? error.message : "Failed to upload banner",
        });
      }
-   } else {
-     throw new TRPCError({
-       code: "BAD_REQUEST",
-       message: "Unsupported banner format. Please use PNG, JPEG, or SVG.",
-     });
-   }
  }

204-236: LGTM: Consistent logo validation pattern

The logo validation follows the same comprehensive pattern as the banner validation, maintaining consistency in the codebase.

Same optimization opportunity applies here - the format checking after validation is redundant since validateBase64Image already handles format validation.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ee073cd and adc8667.

📒 Files selected for processing (11)
  • apps/api/v1/pages/api/users/[userId]/_patch.ts (2 hunks)
  • apps/web/app/api/avatar/[uuid]/route.ts (3 hunks)
  • apps/web/public/static/locales/en/common.json (1 hunks)
  • packages/app-store/_utils/oauth/updateProfilePhotoGoogle.ts (2 hunks)
  • packages/lib/server/avatar.ts (2 hunks)
  • packages/lib/server/imageValidation.ts (1 hunks)
  • packages/trpc/server/routers/viewer/me/updateProfile.handler.ts (2 hunks)
  • packages/trpc/server/routers/viewer/organizations/update.handler.ts (2 hunks)
  • packages/trpc/server/routers/viewer/organizations/updateUser.handler.ts (2 hunks)
  • packages/ui/components/image-uploader/BannerUploader.tsx (1 hunks)
  • packages/ui/components/image-uploader/ImageUploader.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/review.mdc)

Flag excessive Day.js use in performance-critical code. Functions like .add, .diff, .isBefore, and .isAfter are slow, especially in timezone mode. Prefer .utc() for better performance. Where possible, replace with native Date and direct .valueOf() comparisons for faster execution. Recommend using native methods or Day.js .utc() consistently in hot paths like loops.

Files:

  • packages/lib/server/avatar.ts
  • packages/app-store/_utils/oauth/updateProfilePhotoGoogle.ts
  • apps/api/v1/pages/api/users/[userId]/_patch.ts
  • apps/web/app/api/avatar/[uuid]/route.ts
  • packages/trpc/server/routers/viewer/organizations/updateUser.handler.ts
  • packages/trpc/server/routers/viewer/me/updateProfile.handler.ts
  • packages/ui/components/image-uploader/BannerUploader.tsx
  • packages/trpc/server/routers/viewer/organizations/update.handler.ts
  • packages/ui/components/image-uploader/ImageUploader.tsx
  • packages/lib/server/imageValidation.ts
🧠 Learnings (3)
apps/web/app/api/avatar/[uuid]/route.ts (1)

Learnt from: CR
PR: calcom/cal.com#0
File: .cursor/rules/review.mdc:0-0
Timestamp: 2025-07-21T13:54:11.770Z
Learning: Applies to backend/**/*.{ts,tsx} : For Prisma queries: Only select data you need.

apps/web/public/static/locales/en/common.json (1)

Learnt from: bandhan-majumder
PR: #22359
File: packages/lib/server/locales/en/common.json:1336-1339
Timestamp: 2025-07-14T16:31:45.233Z
Learning: When making localization changes for new features, it's often safer to add new strings rather than modify existing ones to avoid breaking existing functionality that depends on the original strings. This approach allows for feature-specific customization while maintaining backward compatibility.

packages/ui/components/image-uploader/ImageUploader.tsx (1)

Learnt from: Anshumancanrock
PR: #22570
File: apps/web/modules/signup-view.tsx:253-253
Timestamp: 2025-07-21T21:33:23.371Z
Learning: In signup-view.tsx, when checking if redirectUrl contains certain strings, using explicit && checks (redirectUrl && redirectUrl.includes()) is preferred over optional chaining (redirectUrl?.includes()) to ensure the result is always a boolean rather than potentially undefined. This approach provides cleaner boolean contracts for downstream conditional logic.

🧬 Code Graph Analysis (6)
packages/app-store/_utils/oauth/updateProfilePhotoGoogle.ts (1)
packages/lib/server/imageValidation.ts (1)
  • validateBase64Image (47-141)
apps/web/app/api/avatar/[uuid]/route.ts (2)
packages/lib/server/imageValidation.ts (1)
  • validateBase64Image (47-141)
packages/lib/constants.ts (2)
  • AVATAR_FALLBACK (91-91)
  • WEBAPP_URL (12-18)
packages/trpc/server/routers/viewer/organizations/updateUser.handler.ts (2)
packages/lib/server/imageValidation.ts (1)
  • validateBase64Image (47-141)
packages/lib/server/avatar.ts (1)
  • uploadAvatar (8-39)
packages/trpc/server/routers/viewer/me/updateProfile.handler.ts (2)
packages/lib/server/imageValidation.ts (1)
  • validateBase64Image (47-141)
packages/lib/server/avatar.ts (1)
  • uploadAvatar (8-39)
packages/ui/components/image-uploader/BannerUploader.tsx (1)
packages/lib/server/imageValidation.ts (1)
  • validateImageFile (146-170)
packages/ui/components/image-uploader/ImageUploader.tsx (1)
packages/lib/server/imageValidation.ts (1)
  • validateImageFile (146-170)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Detect changes
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (16)
packages/lib/server/imageValidation.ts (5)

6-10: LGTM! Well-defined interface.

The interface is properly structured with appropriate optional properties and clear naming conventions.


15-34: LGTM! Comprehensive file signature definitions.

The magic numbers are correctly defined and well-organized. The separation between allowed image formats and dangerous blocked formats enhances security and readability.


39-42: LGTM! Solid helper function implementation.

The bounds checking and byte-by-byte comparison logic is correct and handles edge cases appropriately.


47-141: Excellent security-first validation approach!

The function correctly prioritizes checking dangerous formats before valid ones, implements comprehensive SVG security scanning, and handles edge cases well.


146-170: LGTM! Well-structured file validation with appropriate checks.

The function correctly implements layered validation (MIME type, size, magic numbers) and efficiently reuses the base64 validation logic for consistency.

apps/web/public/static/locales/en/common.json (1)

3420-3428: No functional issues – double-check parity in other locale files

The new image-validation strings are well-formed and correctly inserted above the sentinel line, so this file remains valid JSON.
To avoid “missing translation” warnings at runtime, please add the same keys to the other locale JSON files (e.g. de, es, etc.) or confirm that a fallback mechanism is in place.

packages/lib/server/avatar.ts (3)

6-6: LGTM: Import added for validation utility

The import of validateBase64Image is appropriately placed and necessary for the validation logic.


9-13: LGTM: Early validation prevents processing invalid images

The validation is correctly placed before expensive operations like UUID generation and image processing. The error message includes validation details, which is helpful for debugging.


50-54: LGTM: Consistent validation pattern applied to logo uploads

The same validation pattern is consistently applied to the uploadLogo function, maintaining code consistency and security standards.

packages/app-store/_utils/oauth/updateProfilePhotoGoogle.ts (2)

6-6: LGTM: Import added for OAuth image validation

The import of validateBase64Image is correctly added for validating OAuth profile images.


26-31: LGTM: Proper validation and error handling for OAuth images

The validation correctly prevents processing of invalid images from Google OAuth. The error logging and early return pattern is appropriate for handling validation failures without disrupting the OAuth flow.

apps/api/v1/pages/api/users/[userId]/_patch.ts (1)

6-6: LGTM: Import added for API avatar validation

The import of validateBase64Image is correctly added for validating avatar uploads in the API endpoint.

apps/web/app/api/avatar/[uuid]/route.ts (3)

9-9: LGTM: Import added for stored image validation

The import of validateBase64Image is correctly added for validating stored avatar images before serving.


50-57: Excellent security enhancement: Validation of stored images

This is a great security improvement that validates stored images before serving them. The approach of redirecting to a fallback avatar instead of serving potentially dangerous content is the right defensive strategy.


85-89: LGTM: Comprehensive security headers

The security headers are well-chosen and comprehensive:

  • X-Content-Type-Options: nosniff prevents MIME type confusion attacks
  • Content-Disposition: inline ensures proper handling
  • X-Frame-Options: DENY prevents clickjacking
  • Content-Security-Policy restricts resource loading to prevent XSS

These headers significantly enhance the security posture when serving avatar images.

packages/trpc/server/routers/viewer/organizations/update.handler.ts (1)

6-6: LGTM: Import added for organization image validation

The import of validateBase64Image is correctly added for validating banner and logo images in organization updates.

@Devanshusharma2005 Devanshusharma2005 marked this pull request as ready for review July 28, 2025 11:46
Copy link
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.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between adc8667 and fe1451a.

📒 Files selected for processing (6)
  • apps/api/v1/pages/api/users/[userId]/_patch.ts (2 hunks)
  • apps/web/public/static/locales/en/common.json (1 hunks)
  • packages/trpc/server/routers/viewer/me/updateProfile.handler.ts (2 hunks)
  • packages/ui/components/image-uploader/BannerUploader.tsx (2 hunks)
  • packages/ui/components/image-uploader/ImageUploader.tsx (2 hunks)
  • packages/ui/components/image-uploader/imageValidation.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • apps/web/public/static/locales/en/common.json
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/ui/components/image-uploader/BannerUploader.tsx
  • apps/api/v1/pages/api/users/[userId]/_patch.ts
  • packages/trpc/server/routers/viewer/me/updateProfile.handler.ts
  • packages/ui/components/image-uploader/ImageUploader.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.ts

📄 CodeRabbit Inference Engine (.cursor/rules/review.mdc)

**/*.ts: For Prisma queries, only select data you need; never use include, always use select
Ensure the credential.key field is never returned from tRPC endpoints or APIs

Files:

  • packages/ui/components/image-uploader/imageValidation.ts
**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/review.mdc)

Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js .utc() in hot paths like loops

Files:

  • packages/ui/components/image-uploader/imageValidation.ts
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
PR: calcom/cal.com#0
File: .cursor/rules/review.mdc:0-0
Timestamp: 2025-07-28T11:50:23.918Z
Learning: For large pull requests (>500 lines changed or >10 files touched), advise splitting into smaller, focused PRs by feature, layer, dependency chain, or file/module
🔇 Additional comments (5)
packages/ui/components/image-uploader/imageValidation.ts (5)

1-7: Function signature and documentation look good.

The async function signature with proper typing and internationalization support is well-designed. The JSDoc comment effectively describes the function's purpose.


8-12: File size validation is implemented correctly.

The 5MB limit with decimal-based calculation (5 * 1000000) is appropriate for user-facing applications and aligns with common file size representations.


14-17: MIME type validation provides a good first-level check.

This basic MIME type validation is appropriate as an initial filter, though it's correctly supplemented by magic number validation since MIME types can be easily spoofed.


85-126: Image format validation is comprehensive and accurate.

The magic number validation for PNG, JPEG, GIF, WEBP, BMP, and ICO formats is correctly implemented. The byte signatures are accurate and the logic properly validates legitimate image formats.


128-133: Error handling is robust and follows best practices.

The try-catch block appropriately handles potential exceptions during file processing, and returning false on error ensures safe fallback behavior.

Copy link
Contributor

@Amit91848 Amit91848 left a comment

Choose a reason for hiding this comment

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

Great work @Devanshusharma2005 , haven't tested it yet but looks promising.
The code needs some refactoring and cleanup. Left comments

Also can you whip up a few tests for the validateBase64Image function, devin can probably help here

@github-actions github-actions bot marked this pull request as draft July 30, 2025 07:21
Amit91848
Amit91848 previously approved these changes Aug 4, 2025
Copy link
Contributor

@Amit91848 Amit91848 left a comment

Choose a reason for hiding this comment

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

LGTM!

Amit91848
Amit91848 previously approved these changes Aug 4, 2025
hbjORbj
hbjORbj previously requested changes Aug 4, 2025
Copy link
Contributor

@hbjORbj hbjORbj left a comment

Choose a reason for hiding this comment

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

Would be great if you can check if something like this ensures that images files are still not selectable regardless of switching between All Files <-> Images Files

If there's no way to prevent users from selecting certain file extensions, then we will have to fully rely on the manual validation logic.

Screenshot 2025-08-04 at 5 46 52 PM

@github-actions github-actions bot marked this pull request as draft August 4, 2025 08:47
@Devanshusharma2005
Copy link
Contributor Author

Would be great if you can check if something like this ensures that images files are still not selectable regardless of switching between All Files <-> Images Files

If there's no way to prevent users from selecting certain file extensions, then we will have to fully rely on the manual validation logic.

Screenshot 2025-08-04 at 5 46 52 PM

On Windows, the file picker always includes an “All Files” option, so users can still manually choose a PDF or any unsupported format, even if we specify accept="image/*". So yeah, it seems like we’ll have to rely on manual validation as the real line of defense here.

Maybe I’m missing something though if you find a way that fully enforces it, definitely lmk.

@Devanshusharma2005 Devanshusharma2005 marked this pull request as ready for review August 5, 2025 07:12
@hbjORbj
Copy link
Contributor

hbjORbj commented Aug 11, 2025

@Devanshusharma2005

On Windows, the file picker always includes an “All Files” option, so users can still manually choose a PDF or any unsupported format, even if we specify accept="image/*"

Yeah I'm aware of it. There's this same behavior on Mac. That's why I suggested explicitly using the file extensions and testing. Lmk if it works!

@keithwillcode keithwillcode enabled auto-merge (squash) August 13, 2025 15:42
@keithwillcode keithwillcode dismissed hbjORbj’s stale review August 13, 2025 15:46

I discussed with Devanshu and decided that we can merge like this since even if All Files is shown, other file types are not able to be uploaded. Devanshu is going to continue researching this to see if possible in Windows. For now, this is good to go.

Copy link
Contributor

github-actions bot commented Aug 13, 2025

E2E results are ready!

Copy link
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.

Actionable comments posted: 0

🧹 Nitpick comments (2)
apps/web/public/static/locales/en/common.json (2)

3475-3481: Reduce translation overhead: consolidate file-type-specific errors into a single parameterized message

You’ve added five highly specific strings (PDF/HTML/script/ZIP/executable). Consider replacing them with one generic, parameterized string to minimize duplication and future translation effort. It also aligns with existing patterns like invalid_file_type_extension that accept parameters.

Proposed consolidation (optional):

-  "pdf_files_cannot_be_uploaded_as_images": "PDF files cannot be uploaded as images",
-  "html_files_cannot_be_uploaded_as_images": "HTML files cannot be uploaded as images",
-  "script_files_cannot_be_uploaded_as_images": "Script files cannot be uploaded as images",
-  "zip_files_cannot_be_uploaded_as_images": "ZIP files cannot be uploaded as images",
-  "executable_files_cannot_be_uploaded_as_images": "Executable files cannot be uploaded as images",
+  "unsupported_non_image_file": "Only image files are allowed. Received {{detectedType}}",

This keeps “only_image_files_allowed” for the generic case and provides a single, specific variant that can show the detected type.


3476-3476: Align image-validation messages with the existing parameterized pattern

  • Update the English JSON entry for invalid_image_file_format to mirror invalid_file_type_extension:

    apps/web/public/static/locales/en/common.json
    -  "invalid_image_file_format": "Invalid image file format",
    +  "invalid_image_file_format": "Unsupported image format. Accepted types: {{acceptedTypes}}",
  • Note that only_image_files_allowed isn’t referenced in any code or tests; consider removing this unused key to reduce clutter.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between bf999a8 and 9c4f036.

📒 Files selected for processing (1)
  • apps/web/public/static/locales/en/common.json (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Install dependencies / Yarn install & cache
🔇 Additional comments (1)
apps/web/public/static/locales/en/common.json (1)

3475-3482: Good addition and correct placement above the merge-conflict sentinel

New i18n keys are added in the right place (before ADD_NEW_STRINGS marker) and cover expected error scenarios for image validation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
community Created by Linear-GitHub Sync community-interns The team responsible for reviewing, testing and shipping low/medium community PRs ✨ feature New feature or request ready-for-e2e
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants