-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
feat: add CC/BCC support to mailto handler and email composer #674
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
Conversation
@jlokos is attempting to deploy a commit to the Zero Team on Vercel. A member of the Team first needs to authorize it. |
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughThis change removes the Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Browser
participant MailApp
participant GoogleAPI
User->>Browser: Clicks mailto link
Browser->>MailApp: Navigates to /mail/create/handle-mailto?mailto=...
MailApp->>MailApp: Parses mailto (to, subject, body, cc, bcc)
MailApp->>GoogleAPI: Creates draft with all fields
GoogleAPI-->>MailApp: Returns draft ID
MailApp->>Browser: Redirects to /mail/create?draftId=...
Browser->>MailApp: Loads /mail/create with draft
MailApp->>User: Renders CreateEmail with prefilled fields
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this 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 (5)
apps/mail/components/create/create-email.tsx (3)
120-147
: useEffect to auto-show CC/BCC if initial values exist.
The logic is correct, but note that you also set CC/BCC visibility in another effect (lines 501+). Consider unifying them to minimize repetitive state updates.
501-555
: Additional effect setting CC/BCC states.
Similar to lines 120–147. Consider merging these to reduce duplication.
917-930
: Plus button for file attachments.
This is a creative, minimal UI for adding attachments. For improved accessibility, consider adding anaria-label
to the button or referencing the file input’s label.apps/mail/app/(routes)/mail/compose/handle-mailto/route.ts (2)
14-24
: Use optional chaining for regex matches.The code can be simplified using optional chaining as suggested by the static analysis.
- const emailMatch = mailtoUrl.match(/^mailto:([^?]+)/); - if (emailMatch && emailMatch[1]) { + const emailMatch = mailtoUrl.match(/^mailto:([^?]+)/); + if (emailMatch?.[1]) {🧰 Tools
🪛 Biome (1.9.4)
[error] 22-22: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
26-36
: Use optional chaining for regex matches here too.Similar to the previous comment, optional chaining would improve readability.
- const queryParamsMatch = mailtoUrl.match(/\?(.+)$/); - if (queryParamsMatch && queryParamsMatch[1]) { + const queryParamsMatch = mailtoUrl.match(/\?(.+)$/); + if (queryParamsMatch?.[1]) {🧰 Tools
🪛 Biome (1.9.4)
[error] 28-28: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
apps/mail/app/(routes)/mail/compose/handle-mailto/route.ts
(4 hunks)apps/mail/app/(routes)/mail/compose/page.tsx
(2 hunks)apps/mail/app/api/driver/google.ts
(5 hunks)apps/mail/components/create/create-email.tsx
(17 hunks)apps/mail/components/mail/use-mail.ts
(2 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
apps/mail/app/(routes)/mail/compose/handle-mailto/route.ts
[error] 22-22: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 28-28: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
🔇 Additional comments (27)
apps/mail/components/mail/use-mail.ts (2)
12-13
: New boolean fields align well with CC/BCC toggling.
DefiningshowCc
andshowBcc
for visibility flags is consistent with the rest of the code and appears straightforward.
23-24
: Default initialization is appropriate.
Initializing bothshowCc
andshowBcc
tofalse
in the atom state is a clear design choice—no issues found.apps/mail/app/(routes)/mail/compose/page.tsx (4)
3-4
: Imports look properly structured.
No issues with importingheaders
fromnext/headers
andauth
from@/lib/auth
.
13-14
: Optional CC/BCC support added to query params.
Definingcc?: string;
andbcc?: string;
ensures consistent typed usage everywhere.
40-46
: Properly passing CC/BCC to the create-email component.
ProvidinginitialCc
andinitialBcc
aligns well with the extended functionality for multiple recipients.
50-50
: No functional changes to review.
Line 50 is simply a closing brace; skipping.apps/mail/components/create/create-email.tsx (9)
1-1
: New imports introduced for CC/BCC and attachment UI.
These imports (e.g.,Popover
,PopoverContent
,useMail
, etc.) are relevant to the new CC/BCC and attachments functionality. No concerns on usage.Also applies to: 3-4, 9-10, 17-18, 26-26
58-59
: New props for CC/BCC.
AddinginitialCc
andinitialBcc
props is a clear and flexible approach to pass prefilled recipients.Also applies to: 64-65
70-77
: State management for CC/BCC recipients.
Converting the comma-delimited strings into arrays and storing them inccEmails
/bccEmails
works well.
166-170
: Loading and processing CC/BCC from draft.
Splitting comma-delimited addresses and filtering out empty entries is straightforward.
180-185
: Single mail state update for CC/BCC visibility.
BundlingshowCc
andshowBcc
updates into a single call is efficient.
216-232
: Utility function to process draft emails.
processDraftEmails
gracefully handles arrays and raw strings, ensuring consistent email lists.
365-388
: Form reset now includes CC/BCC.
Clearing all CC/BCC inputs and flags is essential for a complete reset.
423-451
: Including CC/BCC in the final email object.
Conditionally adding CC/BCC preserves backwards compatibility and is suitably guarded bymail.showCc
/mail.showBcc
.
901-901
: Truncating attachment filenames.
truncateFileName(file.name, 20)
is a neat approach to preserve UI readability. No issues found.apps/mail/app/(routes)/mail/compose/handle-mailto/route.ts (6)
5-9
: Good addition of email validation function.The
isValidEmail
function provides a clean, reusable way to validate email addresses using regex. This helps maintain consistent validation throughout the mailto handling flow.
51-61
: Good implementation of CC/BCC decoding.The implementation uses the same error handling pattern as the existing code for subject and body, providing consistent handling of URL-encoded parameters.
68-70
: Good validation and logging before returning parsed data.The function now properly validates email addresses and logs the complete parsed data including CC and BCC fields before returning.
80-80
: Updated function signature to support CC/BCC fields.The
createDraftFromMailto
function signature now correctly accepts the additional CC and BCC fields that were parsed from the mailto URL.
103-106
: Added CC/BCC fields to draft data object.The draft data object now properly includes the CC and BCC fields, ensuring they're passed to the draft creation process.
111-112
: Enhanced logging for draft creation.Added more detailed logging of the draft creation result, which will help with debugging.
apps/mail/app/api/driver/google.ts (6)
42-43
: Added CC/BCC fields to ParsedDraft interface.The interface now properly supports the CC and BCC fields needed for the feature implementation.
54-66
: Well-implemented helper function for email extraction.The
getEmails
helper function efficiently extracts and processes email addresses from headers, reducing code duplication for To, CC, and BCC fields.
85-86
: Added CC/BCC fields to returned parsed draft object.The parsed draft object now correctly includes the CC and BCC fields extracted from the headers.
786-798
: Good implementation of email sanitization.The
sanitizeEmails
helper function properly:
- Handles empty or whitespace-only input
- Splits by commas to handle multiple addresses
- Trims whitespace from each address
- Validates using regex to ensure only valid addresses are included
- Re-joins with proper formatting
This improves the robustness of the CC/BCC handling.
801-823
: Well-structured dynamic header construction.The code now builds email headers dynamically based on the presence of sanitized To, CC, and BCC fields. This approach is more maintainable than the previous implementation and handles optional fields appropriately.
838-855
: Good error handling for draft operations.The try-catch block for draft creation/updating properly logs errors and rethrows them, improving error visibility during debugging while still allowing callers to handle failures.
looks good, thoughts @MrgSub |
✅ Actions performedReview triggered.
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this 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
🧹 Nitpick comments (3)
apps/mail/app/(routes)/mail/compose/handle-mailto/route.ts (1)
6-9
: Email validation function implementationThe email validation uses a simple regex pattern that handles common email formats. While this will work for most cases, consider enhancing it to handle more complex valid email formats according to RFC 5322.
-const isValidEmail = (email: string): boolean => { - const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; - return emailRegex.test(email); +const isValidEmail = (email: string): boolean => { + // More comprehensive regex that handles more edge cases + const emailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; + return emailRegex.test(email); +};apps/mail/components/create/create-email.tsx (2)
10-10
: Remove unused import to keep code clean.It appears that the
useMail
hook is imported but never used within this file. Unused imports may confuse future maintainers, so removing them helps keep the codebase tidy.Apply this diff to remove the unused import:
- import { useMail } from '@/components/mail/use-mail';
183-199
: Consider validating emails during draft parsing.
processDraftEmails
splits addresses but does not check for invalid or incomplete emails (e.g., usingisValidEmail
). If partial/invalid addresses are undesired in the UI, consider adding validation or filtering them out here.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
apps/mail/app/(routes)/mail/compose/handle-mailto/route.ts
(4 hunks)apps/mail/app/(routes)/mail/compose/page.tsx
(2 hunks)apps/mail/app/api/driver/google.ts
(5 hunks)apps/mail/components/create/create-email.tsx
(17 hunks)apps/mail/components/mail/use-mail.ts
(2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
apps/mail/components/create/create-email.tsx (4)
apps/mail/actions/send.ts (1)
sendEmail
(7-58)apps/mail/lib/utils.ts (1)
truncateFileName
(116-123)apps/mail/components/ui/input.tsx (1)
Input
(31-31)apps/mail/components/ui/button.tsx (1)
Button
(55-55)
🔇 Additional comments (30)
apps/mail/components/mail/use-mail.ts (2)
12-13
: State added for CC/BCC UI controlsThe addition of
showCc
andshowBcc
flags to the Config type properly establishes state controls for toggling visibility of these fields in the compose UI. This change supports the broader implementation of CC/BCC support throughout the mail composition flow.
23-24
: Default visibility states correctly initializedGood job initializing both CC and BCC visibility flags to
false
by default, ensuring they start hidden until explicitly toggled by the user. This matches common email client patterns.apps/mail/app/(routes)/mail/compose/page.tsx (3)
3-4
: Appropriate imports addedAdded imports for Next.js headers and authentication support which are necessary for the updated compose page functionality.
13-14
: Interface extended for CC/BCC paramsGood job extending the ComposePageProps interface to include optional cc and bcc query parameters, maintaining proper typing throughout the application.
40-46
: Component props updated to include CC/BCC valuesThe CreateEmail component now receives initialCc and initialBcc props, completing the flow from URL parameters to component state. This ensures consistent handling of CC/BCC fields throughout the email composition lifecycle.
apps/mail/app/(routes)/mail/compose/handle-mailto/route.ts (4)
21-25
: Improved mailto URL parsingThe switch to regex-based parsing for the email address is a good approach, making the code more robust against malformed URLs. The decoding of the extracted email address is also handled correctly.
27-65
: Enhanced query parameter handlingGood implementation of robust parameter extraction with individual try-catch blocks for each field. This ensures that if one parameter fails to decode properly, the others can still be processed successfully.
68-70
: Email validation before returningGood practice to validate the email address before returning the parsed data, ensuring that only valid mailtos are processed.
80-106
: Updated draft creation with CC and BCCThe
createDraftFromMailto
function correctly passes CC and BCC values to the draft creation API. The inclusion of additional logging is also helpful for debugging.apps/mail/app/api/driver/google.ts (6)
42-43
: Extended ParsedDraft interfaceAdding CC and BCC fields to the ParsedDraft interface ensures type safety throughout the application. Good practice to make these optional arrays of strings.
54-66
: Helper function for header extractionThe
getEmails
helper function is a clean abstraction that properly extracts email addresses from various header types. This eliminates code duplication and standardizes the extraction logic.
85-86
: Updated return values with CC/BCC fieldsGood job ensuring the parsed draft object includes the extracted CC and BCC fields, maintaining consistency with the interface extension.
793-806
: Robust email sanitization functionThe
sanitizeEmails
function properly handles validation and sanitization of email addresses, preventing invalid emails from being passed to the API. This will help avoid API errors when handling addresses with spaces or special characters.One suggestion: Consider adding a log message when an invalid email is filtered out to aid debugging.
const sanitizeEmails = (emailStr: string): string => { if (!emailStr || !emailStr.trim()) return ''; return emailStr .split(',') .map(email => email.trim()) .filter(email => { // Basic email validation const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + const isValid = emailRegex.test(email); + if (!isValid && email.trim() !== '') { + console.log(`Filtering out invalid email: ${email}`); + } + return isValid; - return emailRegex.test(email); }) .join(', '); };
808-830
: Proper MIME header constructionThe implementation correctly builds email headers including sanitized CC and BCC fields. This follows email standards and ensures that invalid addresses are filtered out before sending.
846-863
: Enhanced error handlingThe improved try-catch block properly handles both draft creation and update scenarios with appropriate error logging. This makes debugging and error tracing much easier.
apps/mail/components/create/create-email.tsx (15)
59-60
: New props for CC and BCC are clearly integrated.The new
initialCc
andinitialBcc
props align well with the existing pattern for initializing fields. Good job!
65-66
: Type definitions look correct.The optional
initialCc
andinitialBcc
fields are consistent with the rest of the component’s API.
74-74
: Good approach to unify CC/BCC visibility in a single state object.Maintaining both
showCc
andshowBcc
under one object can simplify state updates and reduce duplication.
285-288
: Draft data structure looks consistent.The inclusion of
cc
andbcc
fields in the draft object ties in well withmail.showCc
andmail.showBcc
. This should facilitate a unified approach to saving drafts.
308-322
: Dependencies for thesaveDraft
callback are accurate.All relevant state variables and setters are included, preventing stale closures and ensuring the function reacts correctly to changes.
338-361
: Reset function is well-structured.It clears all relevant form states, ensuring the component can easily start fresh. This is helpful for after-send or new-draft scenarios.
377-394
: Local input checks enhance user experience.Validating
to
,subject
, andmessageContent
before callingsendEmail
prevents unnecessary API calls and gives immediate feedback to users.
399-414
: Conditional CC/BCC handling is seamless.The conditional inclusion of CC/BCC arrays ensures the
sendEmail
action receives only relevant information.
415-421
: Toast notifications provide clarity.Notifying users of success or failure gives appropriate feedback, and calling
resetEmailForm
after sending is a clean finishing touch.
638-646
: UsingrequestAnimationFrame
for focusing is clever.This prevents race conditions with DOM updates when toggling CC visibility. No issues here.
658-668
: BCC toggle logic mirrors CC.Maintaining symmetry in toggling BCC fields keeps the code consistent and easy to reason about.
675-719
: Rendering CC emails and input fields is correct.The chip UI and input handling align with your approach for “To” recipients. Implementation details look consistent.
721-765
: BCC rendering follows the same pattern as CC.Consistent design patterns help reduce errors and simplify future maintenance.
925-941
: Attachment input UI is well-structured.Offering a hidden file input with a visual button is a standard, user-friendly pattern for adding attachments.
946-948
: Disable logic prevents incomplete sends.Requiring valid
to
/subject
/messageContent
before enabling the send button is a sensible safeguard.
// Process to, cc, and bcc email addresses | ||
const toList = processDraftEmails(draft.to); | ||
const ccList = processDraftEmails(draft.cc); | ||
const bccList = processDraftEmails(draft.bcc); | ||
|
||
// Set emails and update mail state in a batch | ||
if (toList.length > 0) { | ||
setToEmails(toList); | ||
} | ||
|
||
if (draft.subject) { | ||
setSubjectInput(draft.subject); | ||
} | ||
|
||
// Single mail state update for both CC and BCC | ||
const mailStateUpdates = { | ||
showCc: ccList.length > 0, | ||
showBcc: bccList.length > 0, | ||
}; | ||
|
||
setMail((prev) => ({ ...prev, ...mailStateUpdates })); | ||
|
||
// Only set cc/bcc emails if there are any | ||
if (ccList.length > 0) { | ||
setCcEmails(ccList); | ||
} | ||
|
||
if (bccList.length > 0) { | ||
setBccEmails(bccList); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handle clearing addresses when a draft has no recipients.
Currently, the code only sets toEmails
, ccEmails
, or bccEmails
if the parsed list is non-empty (length > 0
). This may leave stale emails from a previously loaded draft. Consider always updating these states to ensure they properly clear when empty.
Apply the following diff to fix the stale data risk:
- if (toList.length > 0) {
- setToEmails(toList);
- }
+ setToEmails(toList);
...
- if (ccList.length > 0) {
- setCcEmails(ccList);
- }
+ setCcEmails(ccList);
...
- if (bccList.length > 0) {
- setBccEmails(bccList);
- }
+ setBccEmails(bccList);
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
// Process to, cc, and bcc email addresses | |
const toList = processDraftEmails(draft.to); | |
const ccList = processDraftEmails(draft.cc); | |
const bccList = processDraftEmails(draft.bcc); | |
// Set emails and update mail state in a batch | |
if (toList.length > 0) { | |
setToEmails(toList); | |
} | |
if (draft.subject) { | |
setSubjectInput(draft.subject); | |
} | |
// Single mail state update for both CC and BCC | |
const mailStateUpdates = { | |
showCc: ccList.length > 0, | |
showBcc: bccList.length > 0, | |
}; | |
setMail((prev) => ({ ...prev, ...mailStateUpdates })); | |
// Only set cc/bcc emails if there are any | |
if (ccList.length > 0) { | |
setCcEmails(ccList); | |
} | |
if (bccList.length > 0) { | |
setBccEmails(bccList); | |
} | |
// Process to, cc, and bcc email addresses | |
const toList = processDraftEmails(draft.to); | |
const ccList = processDraftEmails(draft.cc); | |
const bccList = processDraftEmails(draft.bcc); | |
// Set emails and update mail state in a batch | |
setToEmails(toList); | |
if (draft.subject) { | |
setSubjectInput(draft.subject); | |
} | |
// Single mail state update for both CC and BCC | |
const mailStateUpdates = { | |
showCc: ccList.length > 0, | |
showBcc: bccList.length > 0, | |
}; | |
setMail((prev) => ({ ...prev, ...mailStateUpdates })); | |
// Clear or set cc/bcc emails | |
setCcEmails(ccList); | |
setBccEmails(bccList); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe we can do this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@MrgSub Yes, that's exactly what you should do! The suggested change is important because it prevents stale email addresses from persisting.
Currently, if you load a draft without CC/BCC recipients after viewing one that had them, the old addresses would still display because the empty arrays aren't being applied to the state. Always setting these states (even with empty arrays) ensures accurate representation of the current draft.
This is a small but important fix for proper state management. Would you like me to suggest any other improvements to the CC/BCC implementation?
ʕ •ᴥ•ʔ
apps/mail/app/api/driver/google.ts
Outdated
`From: me`, | ||
`To: ${data.to}`, | ||
// Helper function to sanitize email addresses | ||
const sanitizeEmails = (emailStr: string): string => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need this inside createDraft
// Process to, cc, and bcc email addresses | ||
const toList = processDraftEmails(draft.to); | ||
const ccList = processDraftEmails(draft.cc); | ||
const bccList = processDraftEmails(draft.bcc); | ||
|
||
// Set emails and update mail state in a batch | ||
if (toList.length > 0) { | ||
setToEmails(toList); | ||
} | ||
|
||
if (draft.subject) { | ||
setSubjectInput(draft.subject); | ||
} | ||
|
||
// Single mail state update for both CC and BCC | ||
const mailStateUpdates = { | ||
showCc: ccList.length > 0, | ||
showBcc: bccList.length > 0, | ||
}; | ||
|
||
setMail((prev) => ({ ...prev, ...mailStateUpdates })); | ||
|
||
// Only set cc/bcc emails if there are any | ||
if (ccList.length > 0) { | ||
setCcEmails(ccList); | ||
} | ||
|
||
if (bccList.length > 0) { | ||
setBccEmails(bccList); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe we can do this?
@AxelJetpack from understanding the browser should already be handling this (chrome://settings/handlers). I have not run into this issue. If its problematic for others I guess I could add a guard via localStorage. @MrgSub @nizzyabi - once merged I can set a localStorage guard up (if needed) - I would prefer to base it from here since my initial PR #574 was modified in this PR. |
Thank you! I'll see if I can get some more information from the user! :) |
Implements proper handling of CC and BCC fields in mailto links, including: - Parsing CC and BCC values from mailto URLs - Adding CC and BCC headers to MIME messages when creating drafts - Extracting CC and BCC values from draft headers - Validating and sanitizing email addresses - Updating UI to display CC and BCC fields when values are present Enhances the existing mailto protocol handler support from PR Mail-0#574
Removes the redundant /mail/compose route and unifies email creation and draft handling under /mail/create.
a16de52
to
0df55d2
Compare
feat: add CC/BCC support to mailto handler and email composer
Description
This PR adds proper handling of CC and BCC fields in mailto links to the 0.email. When users click on mailto links that include CC or BCC parameters, these values are now correctly parsed, validated, and displayed in the email composer.
Key improvements:
This enhancement builds upon the existing mailto protocol handler support from PR #574, completing the full implementation of the mailto URL standard.
Type of Change
Areas Affected
Testing Done
I've tested this implementation with various mailto link formats including:
Security Considerations
The implementation includes robust validation and sanitization of email addresses to prevent security issues and API errors. Email addresses are validated using regex patterns, and all invalid addresses are filtered out before being sent to the Gmail API.
Checklist
Additional Notes
The implementation addresses a specific issue where email addresses with spaces or special characters in CC/BCC fields would cause API errors. The solution includes:
By submitting this pull request, I confirm that my contribution is made under the terms of the project's license.
Summary by CodeRabbit
New Features
Bug Fixes
Refactor
/mail/create
path.