feat: run onBeforeEmailSend hook before send, expose fromEmail on OutgoingEmail
This commit is contained in:
@@ -980,6 +980,26 @@ export function EmailComposer({
|
|||||||
const inlineAttachments = rewritten?.attachments ?? [];
|
const inlineAttachments = rewritten?.attachments ?? [];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Let plugins veto the send (external-recipient warning, mistyped-domain
|
||||||
|
// guards, etc.). Returning false from any handler aborts before either
|
||||||
|
// the S/MIME or standard JMAP path runs.
|
||||||
|
const sendablePreview: OutgoingEmail = {
|
||||||
|
to: toAddresses,
|
||||||
|
cc: ccAddresses,
|
||||||
|
bcc: bccAddresses,
|
||||||
|
subject,
|
||||||
|
htmlBody: finalHtmlBody || '',
|
||||||
|
textBody: finalBody,
|
||||||
|
identityId: currentIdentity?.id || '',
|
||||||
|
fromEmail,
|
||||||
|
attachments: attachments
|
||||||
|
.filter(att => att.blobId && !att.uploading && !att.error)
|
||||||
|
.map(a => ({ name: a.name, type: a.type || 'application/octet-stream', size: a.size })),
|
||||||
|
inReplyTo: threadingHeaders?.inReplyTo?.[0],
|
||||||
|
};
|
||||||
|
const sendAllowed = await emailHooks.onBeforeEmailSend.intercept(sendablePreview);
|
||||||
|
if (!sendAllowed) return;
|
||||||
|
|
||||||
// S/MIME send pipeline: build raw MIME → sign → encrypt → sendRawEmail
|
// S/MIME send pipeline: build raw MIME → sign → encrypt → sendRawEmail
|
||||||
if ((smimeSign_ || smimeEncrypt_) && client && currentIdentity?.id) {
|
if ((smimeSign_ || smimeEncrypt_) && client && currentIdentity?.id) {
|
||||||
// 1. Resolve S/MIME key
|
// 1. Resolve S/MIME key
|
||||||
@@ -1115,6 +1135,7 @@ export function EmailComposer({
|
|||||||
htmlBody: finalHtmlBody || '',
|
htmlBody: finalHtmlBody || '',
|
||||||
textBody: finalBody,
|
textBody: finalBody,
|
||||||
identityId: currentIdentity?.id || '',
|
identityId: currentIdentity?.id || '',
|
||||||
|
fromEmail,
|
||||||
attachments: uploadedAttachments.map(a => ({ name: a.name, type: a.type, size: a.size })),
|
attachments: uploadedAttachments.map(a => ({ name: a.name, type: a.type, size: a.size })),
|
||||||
inReplyTo: threadingHeaders?.inReplyTo?.[0],
|
inReplyTo: threadingHeaders?.inReplyTo?.[0],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -541,6 +541,8 @@ export interface OutgoingEmail {
|
|||||||
htmlBody: string;
|
htmlBody: string;
|
||||||
textBody: string;
|
textBody: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
|
/** Sender email derived from the active identity (incl. sub-address tag, when set) */
|
||||||
|
fromEmail?: string;
|
||||||
attachments: { name: string; type: string; size: number }[];
|
attachments: { name: string; type: string; size: number }[];
|
||||||
/** Original message id when this is a reply or forward */
|
/** Original message id when this is a reply or forward */
|
||||||
inReplyTo?: string;
|
inReplyTo?: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user