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 39 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

This change introduces comprehensive image validation across both server-side and client-side code to prevent uploading or serving malicious files disguised as images. A new shared module defines file signature (magic number) constants and utility functions for detecting dangerous file types and validating allowed image formats. Server-side, a validateBase64Image function is added and integrated into all avatar, logo, and banner upload/update handlers, as well as Google OAuth profile photo processing. Client-side, a validateImageFile function is introduced and used in image uploader components, replacing previous simple checks. Extensive test suites are added for both validation utilities. New error messages are localized for invalid image uploads, and additional security headers are set when serving images.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

  • Complexity: The change spans both frontend and backend, introduces new shared validation logic, updates multiple upload/update flows, enhances error handling, and adds comprehensive tests. Reviewers must verify security, correctness, and integration across all touchpoints.
  • Scope: 16 files, including new modules, updated handlers, UI components, and test suites.
  • Estimated review time: ~40 minutes, accounting for code, logic, and test coverage review.

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4db7122 and bf999a8.

📒 Files selected for processing (3)
  • apps/web/public/static/locales/en/common.json (1 hunks)
  • packages/ui/components/image-uploader/BannerUploader.tsx (3 hunks)
  • packages/ui/components/image-uploader/ImageUploader.tsx (3 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 (2)
  • packages/ui/components/image-uploader/ImageUploader.tsx
  • packages/ui/components/image-uploader/BannerUploader.tsx
⏰ 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
✨ 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.
    • Explain this complex logic.
    • 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. Examples:
    • @coderabbitai explain this code block.
  • 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 src/utils.ts and explain its main purpose.
    • @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 comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

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

Documentation and Community

  • 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
@github-actions github-actions bot marked this pull request as draft August 1, 2025 10:58
@Devanshusharma2005 Devanshusharma2005 marked this pull request as ready for review August 1, 2025 14:18
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
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!

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
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants