feat: add email domains (#1895)

Implemented Email Domains which allows Platform/Enterprise customers to
send emails to recipients using their custom emails.
This commit is contained in:
David Nguyen
2025-07-24 16:05:00 +10:00
committed by GitHub
parent 07119f0e8d
commit 3409aae411
157 changed files with 5966 additions and 1090 deletions

View File

@ -26,16 +26,25 @@ export const updateOrganisationSettingsRoute = authenticatedProcedure
// Document related settings.
documentVisibility,
documentLanguage,
documentTimezone,
documentDateFormat,
includeSenderDetails,
includeSigningCertificate,
typedSignatureEnabled,
uploadSignatureEnabled,
drawSignatureEnabled,
// Branding related settings.
brandingEnabled,
brandingLogo,
brandingUrl,
brandingCompanyDetails,
// Email related settings.
emailId,
emailReplyTo,
// emailReplyToName,
emailDocumentSettings,
} = data;
if (Object.values(data).length === 0) {
@ -61,6 +70,22 @@ export const updateOrganisationSettingsRoute = authenticatedProcedure
});
}
// Validate that the email ID belongs to the organisation.
if (emailId) {
const email = await prisma.organisationEmail.findFirst({
where: {
id: emailId,
organisationId,
},
});
if (!email) {
throw new AppError(AppErrorCode.NOT_FOUND, {
message: 'Email not found',
});
}
}
const derivedTypedSignatureEnabled =
typedSignatureEnabled ?? organisation.organisationGlobalSettings.typedSignatureEnabled;
const derivedUploadSignatureEnabled =
@ -88,6 +113,8 @@ export const updateOrganisationSettingsRoute = authenticatedProcedure
// Document related settings.
documentVisibility,
documentLanguage,
documentTimezone,
documentDateFormat,
includeSenderDetails,
includeSigningCertificate,
typedSignatureEnabled,
@ -99,6 +126,12 @@ export const updateOrganisationSettingsRoute = authenticatedProcedure
brandingLogo,
brandingUrl,
brandingCompanyDetails,
// Email related settings.
emailId,
emailReplyTo,
// emailReplyToName,
emailDocumentSettings,
},
},
},

View File

@ -1,14 +1,22 @@
import { z } from 'zod';
import { SUPPORTED_LANGUAGE_CODES } from '@documenso/lib/constants/i18n';
import { ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-email';
import { DocumentVisibility } from '@documenso/lib/types/document-visibility';
import {
ZDocumentMetaDateFormatSchema,
ZDocumentMetaTimezoneSchema,
} from '../document-router/schema';
export const ZUpdateOrganisationSettingsRequestSchema = z.object({
organisationId: z.string(),
data: z.object({
// Document related settings.
documentVisibility: z.nativeEnum(DocumentVisibility).optional(),
documentLanguage: z.enum(SUPPORTED_LANGUAGE_CODES).optional(),
documentTimezone: ZDocumentMetaTimezoneSchema.nullish(), // Null means local timezone.
documentDateFormat: ZDocumentMetaDateFormatSchema.optional(),
includeSenderDetails: z.boolean().optional(),
includeSigningCertificate: z.boolean().optional(),
typedSignatureEnabled: z.boolean().optional(),
@ -20,6 +28,12 @@ export const ZUpdateOrganisationSettingsRequestSchema = z.object({
brandingLogo: z.string().optional(),
brandingUrl: z.string().optional(),
brandingCompanyDetails: z.string().optional(),
// Email related settings.
emailId: z.string().nullish(),
emailReplyTo: z.string().email().nullish(),
// emailReplyToName: z.string().optional(),
emailDocumentSettings: ZDocumentEmailSettingsSchema.optional(),
}),
});