-
Notifications
You must be signed in to change notification settings - Fork 498
resend api key config #851
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
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughEmail configuration gains a provider field and support for three modes (shared, standard/SMTP, resend). Backend sets provider: "smtp" when applying legacy email config. Dashboard emails page refactors to use the new config shape and conditional UI/validation. Shared config schema and template types updated accordingly. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor U as User
participant D as Dashboard Page
participant E as EditEmailServerDialog
participant A as stackAdminApp
participant B as Backend
participant C as Config Store
U->>D: Open Project Emails
D->>E: Open Edit Email Server Dialog (emailConfig)
E->>E: Select type (shared | standard | resend)
alt shared
E->>A: Update config { emails.server: { type: "shared" } }
A->>B: Save project config
B->>C: Persist config
C-->>B: OK
B-->>A: OK
A-->>E: OK (toast)
else standard (SMTP)
E->>A: sendTestEmail({ provider:"smtp", host, port, ... })
A->>B: Send test email
B-->>A: Test OK
A->>B: Save { emails.server: { provider:"smtp", ... } }
B->>C: Persist config
C-->>B: OK
B-->>A: OK
A-->>E: OK (toast)
else resend
E->>A: sendTestEmail({ provider:"resend", apiKey, sender... })
A->>B: Send test email
B-->>A: Test OK
A->>B: Save { emails.server: { provider:"resend", ... } }
B->>C: Persist config
C-->>B: OK
B-->>A: OK
A-->>E: OK (toast)
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Pre-merge checks (2 passed, 1 warning)❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
Poem
✨ Finishing touches
🧪 Generate unit tests
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. Comment |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Claude finished @BilalG1's task —— View job PR Review: Resend API Key ConfigurationTodo List:
SummaryThis PR adds Resend email service integration to the Stack Auth platform, providing an alternative to the existing shared and custom SMTP email configurations. The changes span across backend configuration, dashboard UI, and schema updates. Code Quality & Best Practices ✅Positive Aspects:
Minor Issues:
Security Considerations 🔐Concerns Identified:
Recommendations:
Performance Implications ⚡Good Practices:
Potential Issues:
Bugs & Issues 🐛Critical Issues:
Minor Issues:
Test Coverage 📝Missing Tests:
Existing Coverage:
Specific Code Issuesapps/dashboard/src/app/(main)/(protected)/projects/[projectId]/emails/page-client.tsxLines 184-192: Hard-coded Resend configuration // Consider moving to constants
const RESEND_CONFIG = {
host: 'smtp.resend.com',
port: 465,
username: 'resend'
} as const;packages/template/src/lib/stack-app/project-configs/index.tsType mismatch issue: The RecommendationsHigh Priority:
Medium Priority:
Low Priority:
Overall AssessmentThis is a solid implementation that follows good practices and maintains consistency with the existing codebase. The main concerns are around type safety and test coverage. The security implications are well-handled, and the performance impact is minimal. Recommendation: Approve after addressing the type inconsistency issue and adding basic integration tests. |
|
Claude finished @BilalG1's task —— View job PR Review: Resend API Key ConfigurationReview Checklist
AnalysisThis PR adds support for Resend API key configuration in the email settings. The changes include:
✅ Positive Aspects
|
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.
Greptile Summary
This PR introduces support for multiple email service providers in the Stack Auth system by adding a provider field to email configurations. The changes enable users to choose between 'resend' and 'smtp' as email providers, moving away from a previously hardcoded or implicit provider system.
The core change is in the shared configuration schema (packages/stack-shared/src/config/schema.ts), which adds an optional provider field that accepts 'resend' or 'smtp' values, with 'resend' as the default. This change is implemented at the environment configuration level, making provider selection environment-specific.
The dashboard UI (apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/emails/page-client.tsx) has been updated to support the new provider system, restructuring email configuration from a simple type field to a more complex structure with isShared and provider fields. The UI now accesses email configuration through project.useConfig().emails.server instead of the legacy project.config.emailConfig pattern.
The backend (apps/backend/src/lib/projects.tsx) ensures backward compatibility by explicitly setting provider: "smtp" for legacy configurations that didn't previously specify a provider type. This maintains compatibility with existing SMTP configurations while enabling the new Resend provider support.
The template configuration (packages/template/src/lib/stack-app/project-configs/index.ts) has been updated to include 'resend' as a valid email provider type, though it still requires SMTP-specific fields which may not be appropriate for Resend configurations.
Confidence score: 2/5
- This PR has significant implementation inconsistencies that could cause runtime errors in production
- Score reflects critical issues with data access patterns and type mismatches that need resolution before merge
- Pay close attention to the dashboard page-client.tsx file which has mixed old/new configuration patterns
4 files reviewed, 1 comment
| export type AdminEmailConfig = ( | ||
| { | ||
| type: "standard", | ||
| type: "standard" | "resend", |
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.
logic: Adding 'resend' to the type union but requiring SMTP fields (host, port, username, password) creates a configuration mismatch since Resend uses API keys, not SMTP credentials
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.
yea shouldn't this be another union option?
|
Claude finished @BilalG1's task —— View job PR Review: Resend API Key ConfigurationReview Checklist:
Overall AssessmentThis PR adds Resend email provider support to Stack Auth, enabling users to choose between Resend API and custom SMTP for email delivery. While the implementation follows existing patterns well, there are several critical issues that need to be addressed. 🚨 Critical Issues1. Type System InconsistenciesLocation: The export type AdminEmailConfig = (
{
type: "standard" | "resend", // ❌ Both types require same SMTP fields
senderName: string,
senderEmail: string,
host: string, // ❌ Resend doesn't need this
port: number, // ❌ Resend doesn't need this
username: string, // ❌ Resend doesn't need this
password: string, // This is the API key for Resend
}
| { type: "shared" }
);Impact: Runtime errors when Resend configs are processed expecting different field structures. 2. Hard-coded Provider AssignmentLocation: provider: "smtp", // ❌ Always SMTP, ignores actual provider typeImpact: Resend configurations get incorrectly flagged as SMTP in the database. 3. Inconsistent Data Access PatternsLocation: const emailConfig = project.config.emailConfig || throwErr("Email config is not set");Issue: Uses legacy 🛡️ Security Concerns1. API Key Exposure
2. Error Message Leakage
🐛 Bugs & Logic Issues1. Default Provider ValueLocation: provider: "smtp", // ❌ Should be dynamic or default to 'resend'2. Schema Validation MismatchThe definedWhenNotShared(yup.string(), "Host is required"), // ❌ Applied to Resend too3. Hard-coded SMTP ConfigurationLocation: host: 'smtp.resend.com', // ❌ Should be constants
port: 465,
username: 'resend',📊 Performance ImplicationsGood:
Concerns:
🧪 Test Coverage IssuesMissing:
Existing:
🎯 Specific RecommendationsHigh Priority (Must Fix):
Medium Priority:
Low Priority:
🔧 Suggested Code Changes// Fix AdminEmailConfig type
export type AdminEmailConfig =
| {
type: "standard",
senderName: string,
senderEmail: string,
host: string,
port: number,
username: string,
password: string,
}
| {
type: "resend",
senderName: string,
senderEmail: string,
password: string, // API key
}
| {
type: "shared",
};
// Fix provider assignment
provider: dataOptions.email_config.type === 'resend' ? 'resend' : 'smtp',
// Extract constants
const RESEND_CONFIG = {
host: 'smtp.resend.com',
port: 465,
username: 'resend'
} as const;⚡ Final VerdictStatus: While the implementation demonstrates good understanding of the existing architecture, the type system inconsistencies and hard-coded provider assignments create significant bugs that will cause runtime failures. The security and test coverage concerns are also important but not blocking. Recommended Actions:
Once these issues are resolved, this will be a solid addition that properly extends Stack Auth's email capabilities. |
Review by RecurseML🔍 Review performed on e5eb478..d5fa738 ✨ No bugs found, your code is sparkling clean ✅ Files analyzed, no issues (4)• |
|
Claude finished @BilalG1's task —— View job PR Review: Resend Email Provider SupportReview Checklist
SummaryThis PR adds support for Resend email provider to Stack Auth, enabling users to choose between Resend API and custom SMTP for email delivery. The implementation spans across backend configuration, schema updates, dashboard UI, and template types. 🚨 Critical Issues1. Type System InconsistenciesLocation: The export type AdminEmailConfig = (
{
type: "standard" | "resend", // ❌ Both require same SMTP fields
senderName: string,
senderEmail: string,
host: string, // ❌ Resend doesn't need this
port: number, // ❌ Resend doesn't need this
username: string, // ❌ Resend doesn't need this
password: string, // This is the API key for Resend
}
| { type: "shared" }
);Impact: This will cause runtime errors when Resend configurations are processed expecting different field structures. 2. Hard-coded Provider AssignmentLocation: provider: "smtp", // ❌ Always SMTP, ignores actual provider typeImpact: All email configurations, including Resend, get incorrectly stored as 'smtp' in the database. 3. Data Access Pattern InconsistencyLocation: const emailConfig = project.config.emailConfig || throwErr("Email config is not set");Issue: Uses legacy 🛡️ Security Concerns1. API Key Storage & Transmission
2. Error Message Exposure
🐛 Bugs & Logic Issues1. Schema Default ProviderLocation: provider: "smtp", // ❌ Should be dynamic based on actual configuration2. Hard-coded SMTP ConfigurationLocation: host: 'smtp.resend.com', // ❌ Should be constants
port: 465,
username: 'resend',Issue: These values are hard-coded and should be moved to configuration constants. 3. Schema Validation MismatchThe schema validation at line 203 allows 'resend' provider but the validation functions may still require SMTP fields. 📊 Performance & Code QualityPositive Aspects:
Areas for Improvement:
🧪 Test CoverageMissing:
Existing:
🎯 Specific RecommendationsHigh Priority (Must Fix):
Medium Priority:
Low Priority:
🔧 Suggested Code Changes// Fix AdminEmailConfig type
export type AdminEmailConfig =
| {
type: "standard",
senderName: string,
senderEmail: string,
host: string,
port: number,
username: string,
password: string,
}
| {
type: "resend",
senderName: string,
senderEmail: string,
password: string, // API key
}
| {
type: "shared",
};
// Fix provider assignment
provider: dataOptions.email_config.type === 'resend' ? 'resend' : 'smtp',
// Extract constants
const RESEND_CONFIG = {
host: 'smtp.resend.com',
port: 465,
username: 'resend'
} as const;⚡ Final AssessmentStatus: While the implementation demonstrates good understanding of the existing architecture, the type system inconsistencies and hard-coded provider assignments create critical bugs that will cause runtime failures. The security considerations and test coverage gaps are important but not immediately blocking. Recommended Actions:
Once these issues are resolved, this will be a solid addition to Stack Auth's email capabilities. |
|
Claude encountered an error —— View job PR Review: Resend Email Provider Support
|
| export type AdminEmailConfig = ( | ||
| { | ||
| type: "standard", | ||
| type: "standard" | "resend", |
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.
yea shouldn't this be another union option?
N2D4
left a comment
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.
wait, where do you actually send the emails with resend?
I'm still sending through smtp, just using resend option to prefill smtp properties |
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
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/emails/page-client.tsx (2)
284-292: Use environment server config for test-sending; current code reads legacyproject.config.emailConfig.After configuring via
updateConfig,project.config.emailConfigmay be unset, causing false “Email config is not set.” Build the test payload fromproject.useConfig().emails.server.onSubmit={async (values) => { - const emailConfig = project.config.emailConfig || throwErr("Email config is not set"); - if (emailConfig.type === 'shared') throwErr("Shared email server cannot be used for testing"); + const server = project.useConfig().emails.server; + if (server.isShared) throwErr("Shared email server cannot be used for testing"); + + const emailConfig: AdminEmailConfig = server.provider === 'resend' + ? { + type: 'resend', + host: server.host ?? 'smtp.resend.com', + port: server.port ?? 465, + username: server.username ?? 'resend', + password: server.password ?? throwErr("Missing Resend API key"), + senderEmail: server.senderEmail ?? throwErr("Missing sender email"), + senderName: server.senderName ?? throwErr("Missing sender name"), + } + : { + type: 'standard', + host: server.host ?? throwErr("Missing SMTP host"), + port: server.port ?? throwErr("Missing SMTP port"), + username: server.username ?? throwErr("Missing SMTP username"), + password: server.password ?? throwErr("Missing SMTP password"), + senderEmail: server.senderEmail ?? throwErr("Missing sender email"), + senderName: server.senderName ?? throwErr("Missing sender name"), + };
407-417: Replace blocking error toast with inline Alert per UI guidelines.Show a form-level Alert instead of a destructive toast when preventing close.
const handleNext = async () => { if (selectedUsers.length === 0) { - toast({ - title: "No recipients selected", - description: "Please select at least one recipient to send the email.", - variant: "destructive", - }); + setRecipientError("Please select at least one recipient to send the email."); return "prevent-close" as const; } setStage('data'); return "prevent-close" as const; };Add state and render:
const [selectedUsers, setSelectedUsers] = useState<ServerUser[]>([]); const [stage, setStage] = useState<'recipients' | 'data'>('recipients'); + const [recipientError, setRecipientError] = useState<string | null>(null);{stage === 'recipients' ? ( <TeamMemberSearchTable action={(user) => ( <Button size="sm" variant="outline" - onClick={() => setSelectedUsers(users => + onClick={() => { setRecipientError(null); setSelectedUsers(users => users.some(u => u.id === user.id) ? users.filter(u => u.id !== user.id) : [...users, user] - )} + )}} > {selectedUsers.some(u => u.id === user.id) ? 'Remove' : 'Add'} </Button> )} /> ) : ({stage === 'recipients' && recipientError && ( <Alert variant="destructive">{recipientError}</Alert> )}
♻️ Duplicate comments (1)
apps/backend/src/lib/projects.tsx (1)
211-221: Set provider dynamically for 'resend' instead of hardcoding "smtp".Map
providerbased ondataOptions.email_config.typeso Resend configs don’t get mislabeled as SMTP.senderEmail: dataOptions.email_config.sender_email, - provider: "smtp", + provider: dataOptions.email_config.type === 'resend' ? 'resend' : 'smtp',
🧹 Nitpick comments (4)
packages/stack-shared/src/config/schema.ts (1)
212-223: Provider field addition looks good; consider cross-field constraints.Nice addition. As a follow-up, add cross-field validation (e.g., when
server.isShared === true, disallow other fields; whenprovider === 'resend', ignore/forbid customhost/port/username).packages/template/src/lib/stack-app/project-configs/index.ts (1)
40-50: Clarify 'resend' shape or document SMTP mapping to reduce confusion.Current union requires SMTP fields for
type: "resend", which can be confusing. Two options:
- Non-breaking: document that for Resend,
usernamemust be"resend",host=smtp.resend.com,port=465, andpasswordis the API key.- Breaking (cleaner): make
resendvariant accept{ apiKey, senderName, senderEmail }only and set SMTP defaults internally.Non-breaking doc update:
export type AdminEmailConfig = ( { - type: "standard" | "resend", + /** + * For "resend": use SMTP relay — host "smtp.resend.com", port 465, username "resend", password = Resend API key. + */ + type: "standard" | "resend", senderName: string, senderEmail: string, host: string, port: number, username: string, password: string, }apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/emails/page-client.tsx (2)
487-489: Wording: include Resend, not just “custom SMTP server”.Users on Resend should be guided too.
- You are using a shared email server. If you want to send manual emails, you need to configure a custom SMTP server. + You are using a shared email server. To send manual emails, configure your own email server (SMTP or Resend).
134-165: Happy path UX: success toast is fine; consider surfacing server-side validation errors inline.Optional: parse known error codes into field errors to focus the user on what to fix.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
apps/backend/src/lib/projects.tsx(1 hunks)apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/emails/page-client.tsx(9 hunks)packages/stack-shared/src/config/schema.ts(2 hunks)packages/template/src/lib/stack-app/project-configs/index.ts(2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Prefer ES6 Map over Record when representing key–value collections
Files:
apps/backend/src/lib/projects.tsxpackages/stack-shared/src/config/schema.tspackages/template/src/lib/stack-app/project-configs/index.tsapps/dashboard/src/app/(main)/(protected)/projects/[projectId]/emails/page-client.tsx
packages/template/**
📄 CodeRabbit inference engine (AGENTS.md)
When modifying the SDK copies, make changes in packages/template (source of truth)
Files:
packages/template/src/lib/stack-app/project-configs/index.ts
{apps/dashboard,apps/dev-launchpad,packages/stack-ui,packages/react}/**/*.{tsx,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
For blocking alerts and errors in UI, do not use toast notifications; use alerts instead
Files:
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/emails/page-client.tsx
{apps/dashboard,apps/dev-launchpad,packages/stack-ui,packages/react}/**/*.{tsx,jsx,css}
📄 CodeRabbit inference engine (AGENTS.md)
Keep hover/click animations snappy; avoid pre-transition delays on hover and apply transitions after the action (e.g., fade-out on hover end)
Files:
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/emails/page-client.tsx
🧬 Code graph analysis (2)
packages/stack-shared/src/config/schema.ts (1)
packages/stack-shared/src/schema-fields.ts (1)
yupString(187-190)
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/emails/page-client.tsx (7)
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates/page-client.tsx (1)
PageClient(13-80)apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/use-admin-app.tsx (1)
useAdminApp(27-34)packages/stack-shared/src/config/schema.ts (1)
CompleteConfig(993-993)packages/template/src/lib/stack-app/projects/index.ts (1)
AdminProject(16-40)packages/stack-shared/src/schema-fields.ts (1)
strictEmailSchema(448-448)packages/template/src/lib/stack-app/project-configs/index.ts (1)
AdminEmailConfig(40-53)apps/dashboard/src/components/form-fields.tsx (1)
InputField(59-97)
🪛 Biome (2.1.2)
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/emails/page-client.tsx
[error] 83-83: Do not add then to an object.
(lint/suspicious/noThenProperty)
⏰ 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). (9)
- GitHub Check: setup-tests
- GitHub Check: lint_and_build (latest)
- GitHub Check: restart-dev-and-test
- GitHub Check: build (22.x)
- GitHub Check: docker
- GitHub Check: docker
- GitHub Check: all-good
- GitHub Check: build (22.x)
- GitHub Check: Security Check
🔇 Additional comments (1)
packages/stack-shared/src/config/schema.ts (1)
450-456: Defaulting provider to "smtp" at org level is reasonable.No issues from me; aligns with current defaults.
| function definedWhenTypeIsOneOf<S extends yup.AnyObject>(schema: S, types: string[], message: string): S { | ||
| return schema.when('type', { | ||
| is: 'standard', | ||
| is: (t: string) => types.includes(t), | ||
| then: (schema: S) => schema.defined(message), | ||
| otherwise: (schema: S) => schema.optional() | ||
| }); | ||
| } |
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.
Fix Biome “noThenProperty” lint error and broaden generic.
Use the functional when builder to avoid a then property and accept any Yup schema, not just objects.
-function definedWhenTypeIsOneOf<S extends yup.AnyObject>(schema: S, types: string[], message: string): S {
- return schema.when('type', {
- is: (t: string) => types.includes(t),
- then: (schema: S) => schema.defined(message),
- otherwise: (schema: S) => schema.optional()
- });
-}
+function definedWhenTypeIsOneOf<S extends yup.AnySchema>(schema: S, types: string[], message: string): S {
+ // Avoid "then" property (thenable) objects per lint rule.
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ return (schema as any).when('type', (val: unknown, s: S) =>
+ types.includes(String(val)) ? s.defined(message) : s.optional()
+ );
+}📝 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.
| function definedWhenTypeIsOneOf<S extends yup.AnyObject>(schema: S, types: string[], message: string): S { | |
| return schema.when('type', { | |
| is: 'standard', | |
| is: (t: string) => types.includes(t), | |
| then: (schema: S) => schema.defined(message), | |
| otherwise: (schema: S) => schema.optional() | |
| }); | |
| } | |
| function definedWhenTypeIsOneOf<S extends yup.AnySchema>(schema: S, types: string[], message: string): S { | |
| // Avoid "then" property (thenable) objects per lint rule. | |
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | |
| return (schema as any).when('type', (val: unknown, s: S) => | |
| types.includes(String(val)) ? s.defined(message) : s.optional() | |
| ); | |
| } |
🧰 Tools
🪛 Biome (2.1.2)
[error] 83-83: Do not add then to an object.
(lint/suspicious/noThenProperty)
🤖 Prompt for AI Agents
In
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/emails/page-client.tsx
around lines 80 to 86, the helper currently uses the object form of yup.when
(causing the Biome noThenProperty lint error) and constrains the generic to
yup.AnyObject; change the signature to accept any Yup schema (e.g. S extends
yup.Schema<any>) and switch to the functional when builder: call
schema.when('type', (typeValue, currentSchema) => types.includes(typeValue as
string) ? currentSchema.defined(message) : currentSchema.optional()), removing
the object with then/otherwise to satisfy the linter and broaden the accepted
schema type.

https://www.loom.com/share/11affd2a119549c18a4056ad5db34cb6?sid=c86dd093-b8ca-4600-afb1-dda78e40b6a5
Important
Adds support for 'resend' email provider, updating configurations, schemas, and UI components to handle the new provider.
createOrUpdateProjectWithLegacyConfig()inprojects.tsx.PageClientinpage-client.tsxto handle 'resend' provider in email configuration.EditEmailServerDialogto include 'resend' option and handle its configuration.environmentConfigSchemainschema.tsto include 'resend' as a valid provider.AdminEmailConfigtype to include 'resend' inproject-configs/index.ts.SendEmailDialogandTestSendingDialoginpage-client.tsxto handle 'resend' provider.EditEmailServerDialogto support 'resend' specific fields like API Key.This description was created by
for 615fd72. You can customize this summary. It will automatically update as commits are pushed.
Summary by CodeRabbit
New Features
Improvements
Chores