mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
fix(emails): fix base URL
This commit is contained in:
@@ -3,12 +3,11 @@ import { Resend } from 'resend'
|
||||
import { z } from 'zod'
|
||||
import { env } from '@/lib/env'
|
||||
import { createLogger } from '@/lib/logs/console-logger'
|
||||
import { getBaseDomain } from '@/lib/urls/utils'
|
||||
import { getEmailDomain } from '@/lib/urls/utils'
|
||||
|
||||
const resend = env.RESEND_API_KEY ? new Resend(env.RESEND_API_KEY) : null
|
||||
const logger = createLogger('HelpAPI')
|
||||
|
||||
// Define schema for validation
|
||||
const helpFormSchema = z.object({
|
||||
email: z.string().email('Invalid email address'),
|
||||
subject: z.string().min(1, 'Subject is required'),
|
||||
@@ -99,8 +98,8 @@ ${message}
|
||||
|
||||
// Send email using Resend
|
||||
const { data, error } = await resend.emails.send({
|
||||
from: `Sim Studio <noreply@${getBaseDomain()}>`,
|
||||
to: [`help@${getBaseDomain()}`],
|
||||
from: `Sim Studio <noreply@${getEmailDomain()}>`,
|
||||
to: [`help@${getEmailDomain()}`],
|
||||
subject: `[${type.toUpperCase()}] ${subject}`,
|
||||
replyTo: email,
|
||||
text: emailText,
|
||||
@@ -122,7 +121,7 @@ ${message}
|
||||
// Send confirmation email to the user
|
||||
await resend.emails
|
||||
.send({
|
||||
from: `Sim Studio <noreply@${getBaseDomain()}>`,
|
||||
from: `Sim Studio <noreply@${getEmailDomain()}>`,
|
||||
to: [email],
|
||||
subject: `Your ${type} request has been received: ${subject}`,
|
||||
text: `
|
||||
@@ -137,8 +136,8 @@ ${images.length > 0 ? `You attached ${images.length} image(s).` : ''}
|
||||
|
||||
Best regards,
|
||||
The Sim Studio Team
|
||||
`,
|
||||
replyTo: `help@${getBaseDomain()}`,
|
||||
`,
|
||||
replyTo: `help@${getEmailDomain()}`,
|
||||
})
|
||||
.catch((err) => {
|
||||
logger.warn(`[${requestId}] Failed to send confirmation email`, err)
|
||||
|
||||
@@ -7,7 +7,7 @@ import { WorkspaceInvitationEmail } from '@/components/emails/workspace-invitati
|
||||
import { getSession } from '@/lib/auth'
|
||||
import { env } from '@/lib/env'
|
||||
import { createLogger } from '@/lib/logs/console-logger'
|
||||
import { getBaseDomain } from '@/lib/urls/utils'
|
||||
import { getEmailDomain } from '@/lib/urls/utils'
|
||||
import { db } from '@/db'
|
||||
import { user, workspace, workspaceInvitation, workspaceMember } from '@/db/schema'
|
||||
|
||||
@@ -229,7 +229,7 @@ async function sendInvitationEmail({
|
||||
}
|
||||
|
||||
await resend.emails.send({
|
||||
from: `noreply@${getBaseDomain()}`,
|
||||
from: `noreply@${getEmailDomain()}`,
|
||||
to,
|
||||
subject: `You've been invited to join "${workspaceName}" on Sim Studio`,
|
||||
html: emailHtml,
|
||||
|
||||
@@ -17,7 +17,7 @@ import { createLogger } from '@/lib/logs/console-logger'
|
||||
import { db } from '@/db'
|
||||
import * as schema from '@/db/schema'
|
||||
import { env } from './env'
|
||||
import { getBaseDomain } from './urls/utils'
|
||||
import { getEmailDomain } from './urls/utils'
|
||||
|
||||
const logger = createLogger('Auth')
|
||||
|
||||
@@ -147,7 +147,7 @@ export const auth = betterAuth({
|
||||
const html = await renderPasswordResetEmail(username, url)
|
||||
|
||||
const result = await resend.emails.send({
|
||||
from: `Sim Studio <team@${getBaseDomain()}>`,
|
||||
from: `Sim Studio <team@${getEmailDomain()}>`,
|
||||
to: user.email,
|
||||
subject: getEmailSubject('reset-password'),
|
||||
html,
|
||||
@@ -189,7 +189,7 @@ export const auth = betterAuth({
|
||||
|
||||
// In production, send an actual email
|
||||
const result = await resend.emails.send({
|
||||
from: `Sim Studio <onboarding@${getBaseDomain()}>`,
|
||||
from: `Sim Studio <onboarding@${getEmailDomain()}>`,
|
||||
to: data.email,
|
||||
subject: getEmailSubject(data.type),
|
||||
html,
|
||||
@@ -1144,7 +1144,7 @@ export const auth = betterAuth({
|
||||
)
|
||||
|
||||
await resend.emails.send({
|
||||
from: `Sim Studio <team@${getBaseDomain()}>`,
|
||||
from: `Sim Studio <team@${getEmailDomain()}>`,
|
||||
to: invitation.email,
|
||||
subject: `${inviterName} has invited you to join ${organization.name} on Sim Studio`,
|
||||
html,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Resend } from 'resend'
|
||||
import { createLogger } from '@/lib/logs/console-logger'
|
||||
import { env } from './env'
|
||||
import { getBaseDomain } from './urls/utils'
|
||||
import { getEmailDomain } from './urls/utils'
|
||||
|
||||
interface EmailOptions {
|
||||
to: string
|
||||
@@ -42,7 +42,7 @@ export async function sendEmail({
|
||||
from,
|
||||
}: EmailOptions): Promise<SendEmailResult> {
|
||||
try {
|
||||
const senderEmail = from || `noreply@${getBaseDomain()}`
|
||||
const senderEmail = from || `noreply@${getEmailDomain()}`
|
||||
|
||||
if (!resend) {
|
||||
logger.info('Email not sent (Resend not configured):', {
|
||||
@@ -90,7 +90,7 @@ export async function sendBatchEmails({
|
||||
emails,
|
||||
}: BatchEmailOptions): Promise<BatchSendEmailResult> {
|
||||
try {
|
||||
const senderEmail = `noreply@${getBaseDomain()}`
|
||||
const senderEmail = `noreply@${getEmailDomain()}`
|
||||
const results: SendEmailResult[] = []
|
||||
|
||||
if (!resend) {
|
||||
@@ -98,7 +98,6 @@ export async function sendBatchEmails({
|
||||
emailCount: emails.length,
|
||||
})
|
||||
|
||||
// Create mock results for each email
|
||||
emails.forEach(() => {
|
||||
results.push({
|
||||
success: true,
|
||||
@@ -115,7 +114,6 @@ export async function sendBatchEmails({
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare emails for batch sending
|
||||
const batchEmails = emails.map((email) => ({
|
||||
from: `Sim Studio <${email.from || senderEmail}>`,
|
||||
to: email.to,
|
||||
@@ -123,8 +121,6 @@ export async function sendBatchEmails({
|
||||
html: email.html,
|
||||
}))
|
||||
|
||||
// Send batch emails (maximum 100 per batch as per Resend API limits)
|
||||
// Process in chunks of 50 to be safe
|
||||
const BATCH_SIZE = 50
|
||||
let allSuccessful = true
|
||||
|
||||
|
||||
@@ -39,3 +39,17 @@ export function getBaseDomain(): string {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the domain for email addresses, stripping www subdomain for Resend compatibility
|
||||
* @returns The email domain (e.g., 'simstudio.ai' instead of 'www.simstudio.ai')
|
||||
*/
|
||||
export function getEmailDomain(): string {
|
||||
try {
|
||||
const baseDomain = getBaseDomain()
|
||||
return baseDomain.startsWith('www.') ? baseDomain.substring(4) : baseDomain
|
||||
} catch (_e) {
|
||||
const isProd = process.env.NODE_ENV === 'production'
|
||||
return isProd ? 'simstudio.ai' : 'localhost:3000'
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user