Compare commits

..
2 Commits
Author SHA1 Message Date
radoslaw.smolinski 4f08e9ea4d 1.0.15 2026-08-22 23:05:06 +02:00
radoslaw.smolinski 67347f1e34 graph: sender display name from panel 2026-08-22 23:05:05 +02:00
3 changed files with 24 additions and 16 deletions
+22 -14
View File
@@ -89,18 +89,19 @@ import { getSiteIntegrations } from '../payload/index.js';
sent: false sent: false
}; };
} }
// The panel's from-address is used as Reply-To, NOT as the message From. // Display name on the From, WITHOUT triggering Send-As.
// //
// Why: app-only Graph sends from GRAPH_SENDER's mailbox. If we also set a // The trick: we may set a `from` as long as its ADDRESS stays the sender
// `from` that differs from that mailbox, Exchange demands "Send As" // mailbox (GRAPH_SENDER) — only the display NAME changes. Exchange only
// permission on it and rejects with ErrorSendAsDenied otherwise. So we // demands Send-As when the from ADDRESS differs from the mailbox, so a
// never override `from` — Graph stamps the mail as GRAPH_SENDER (the // same-address / custom-name From is allowed and gives each project its
// mailbox we legitimately own) — and route replies to the panel address // own sender label (e.g. "Kancelaria Kędzierski") over the shared mailbox.
// via Reply-To. Recipients see the mail from forms@… but replying reaches //
// the real destination. No Send-As needed. // The panel's from-address becomes Reply-To (so replies reach the client),
// and the panel's from-name becomes the sender display name.
const panel = await getSiteIntegrations(payload); const panel = await getSiteIntegrations(payload);
const replyToAddress = panel.smtpFromAddress || undefined; const replyToAddress = panel.smtpFromAddress || undefined;
const replyToName = panel.smtpFromName || undefined; const senderName = panel.smtpFromName || undefined;
const to = toRecipients(message.to); const to = toRecipients(message.to);
if (to.length === 0) { if (to.length === 0) {
payload.logger.error('[ipal] Email not sent: no valid recipient.'); payload.logger.error('[ipal] Email not sent: no valid recipient.');
@@ -116,10 +117,7 @@ import { getSiteIntegrations } from '../payload/index.js';
const replyTo = message.replyTo ? toRecipients(message.replyTo) : replyToAddress ? [ const replyTo = message.replyTo ? toRecipients(message.replyTo) : replyToAddress ? [
{ {
emailAddress: { emailAddress: {
address: replyToAddress, address: replyToAddress
...replyToName ? {
name: replyToName
} : {}
} }
} }
] : []; ] : [];
@@ -136,7 +134,17 @@ import { getSiteIntegrations } from '../payload/index.js';
...message.bcc ? { ...message.bcc ? {
bccRecipients: toRecipients(message.bcc) bccRecipients: toRecipients(message.bcc)
} : {}, } : {},
// NO `from` — Graph uses GRAPH_SENDER's own mailbox, so no Send-As. // From with the sender's OWN address (no Send-As) plus an optional
// display name from the panel. Omit entirely when no name is set —
// Graph then uses the mailbox's default name.
...senderName ? {
from: {
emailAddress: {
name: senderName,
address: env.sender
}
}
} : {},
...replyTo.length > 0 ? { ...replyTo.length > 0 ? {
replyTo replyTo
} : {} } : {}
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@intecion/ipal-kit", "name": "@intecion/ipal-kit",
"version": "1.0.14", "version": "1.0.15",
"description": "Intecion Payload Advanced Library — a Payload CMS 3 plugin: i18n, SEO, forms, consent, analytics, blog/archives.", "description": "Intecion Payload Advanced Library — a Payload CMS 3 plugin: i18n, SEO, forms, consent, analytics, blog/archives.",
"license": "MIT", "license": "MIT",
"repository": { "repository": {