mirror of
https://github.com/documenso/documenso.git
synced 2026-07-27 02:15:05 +10:00
feat: add header metadata to emails (#2927)
This commit is contained in:
@@ -16,6 +16,7 @@ import { createElement } from 'react';
|
|||||||
import { getI18nInstance } from '../../../client-only/providers/i18n-server';
|
import { getI18nInstance } from '../../../client-only/providers/i18n-server';
|
||||||
import { NEXT_PUBLIC_WEBAPP_URL } from '../../../constants/app';
|
import { NEXT_PUBLIC_WEBAPP_URL } from '../../../constants/app';
|
||||||
import { RECIPIENT_ROLE_TO_EMAIL_TYPE, RECIPIENT_ROLES_DESCRIPTION } from '../../../constants/recipient-roles';
|
import { RECIPIENT_ROLE_TO_EMAIL_TYPE, RECIPIENT_ROLES_DESCRIPTION } from '../../../constants/recipient-roles';
|
||||||
|
import { buildEnvelopeEmailHeaders } from '../../../server-only/email/build-envelope-email-headers';
|
||||||
import { getEmailContext } from '../../../server-only/email/get-email-context';
|
import { getEmailContext } from '../../../server-only/email/get-email-context';
|
||||||
import { assertOrganisationRatesAndLimits } from '../../../server-only/rate-limit/assert-organisation-rates-and-limits';
|
import { assertOrganisationRatesAndLimits } from '../../../server-only/rate-limit/assert-organisation-rates-and-limits';
|
||||||
import { updateRecipientNextReminder } from '../../../server-only/recipient/update-recipient-next-reminder';
|
import { updateRecipientNextReminder } from '../../../server-only/recipient/update-recipient-next-reminder';
|
||||||
@@ -224,6 +225,11 @@ export const run = async ({ payload, io }: { payload: TSendSigningEmailJobDefini
|
|||||||
subject: renderCustomEmailTemplate(documentMeta?.subject || emailSubject, customEmailTemplate),
|
subject: renderCustomEmailTemplate(documentMeta?.subject || emailSubject, customEmailTemplate),
|
||||||
html,
|
html,
|
||||||
text,
|
text,
|
||||||
|
headers: buildEnvelopeEmailHeaders({
|
||||||
|
userId,
|
||||||
|
envelopeId: envelope.id,
|
||||||
|
teamId: envelope.teamId,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { createElement } from 'react';
|
|||||||
import { getI18nInstance } from '../../../client-only/providers/i18n-server';
|
import { getI18nInstance } from '../../../client-only/providers/i18n-server';
|
||||||
import { NEXT_PUBLIC_WEBAPP_URL } from '../../../constants/app';
|
import { NEXT_PUBLIC_WEBAPP_URL } from '../../../constants/app';
|
||||||
import { RECIPIENT_ROLES_DESCRIPTION } from '../../../constants/recipient-roles';
|
import { RECIPIENT_ROLES_DESCRIPTION } from '../../../constants/recipient-roles';
|
||||||
|
import { buildEnvelopeEmailHeaders } from '../../../server-only/email/build-envelope-email-headers';
|
||||||
import { getEmailContext } from '../../../server-only/email/get-email-context';
|
import { getEmailContext } from '../../../server-only/email/get-email-context';
|
||||||
import { assertOrganisationRatesAndLimits } from '../../../server-only/rate-limit/assert-organisation-rates-and-limits';
|
import { assertOrganisationRatesAndLimits } from '../../../server-only/rate-limit/assert-organisation-rates-and-limits';
|
||||||
import { updateRecipientNextReminder } from '../../../server-only/recipient/update-recipient-next-reminder';
|
import { updateRecipientNextReminder } from '../../../server-only/recipient/update-recipient-next-reminder';
|
||||||
@@ -211,6 +212,11 @@ export const run = async ({ payload, io }: { payload: TProcessSigningReminderJob
|
|||||||
subject: emailSubject,
|
subject: emailSubject,
|
||||||
html,
|
html,
|
||||||
text,
|
text,
|
||||||
|
headers: buildEnvelopeEmailHeaders({
|
||||||
|
userId: envelope.userId,
|
||||||
|
envelopeId: envelope.id,
|
||||||
|
teamId: envelope.teamId,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
await prisma.documentAuditLog.create({
|
await prisma.documentAuditLog.create({
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import { isDocumentCompleted } from '../../utils/document';
|
|||||||
import type { EnvelopeIdOptions } from '../../utils/envelope';
|
import type { EnvelopeIdOptions } from '../../utils/envelope';
|
||||||
import { isRecipientEmailValidForSending } from '../../utils/recipients';
|
import { isRecipientEmailValidForSending } from '../../utils/recipients';
|
||||||
import { renderEmailWithI18N } from '../../utils/render-email-with-i18n';
|
import { renderEmailWithI18N } from '../../utils/render-email-with-i18n';
|
||||||
|
import { buildEnvelopeEmailHeaders } from '../email/build-envelope-email-headers';
|
||||||
import { getEmailContext } from '../email/get-email-context';
|
import { getEmailContext } from '../email/get-email-context';
|
||||||
import { getEnvelopeWhereInput } from '../envelope/get-envelope-by-id';
|
import { getEnvelopeWhereInput } from '../envelope/get-envelope-by-id';
|
||||||
import { assertOrganisationRatesAndLimits } from '../rate-limit/assert-organisation-rates-and-limits';
|
import { assertOrganisationRatesAndLimits } from '../rate-limit/assert-organisation-rates-and-limits';
|
||||||
@@ -255,6 +256,11 @@ export const resendDocument = async ({ id, userId, recipients, teamId, requestMe
|
|||||||
: emailSubject,
|
: emailSubject,
|
||||||
html,
|
html,
|
||||||
text,
|
text,
|
||||||
|
headers: buildEnvelopeEmailHeaders({
|
||||||
|
userId: envelope.userId,
|
||||||
|
envelopeId: envelope.id,
|
||||||
|
teamId: envelope.teamId,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
await prisma.documentAuditLog.create({
|
await prisma.documentAuditLog.create({
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
export type BuildEnvelopeEmailHeadersOptions = {
|
||||||
|
userId: number;
|
||||||
|
envelopeId: string;
|
||||||
|
teamId: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds opaque sender-attribution headers stamped onto outgoing user-triggered
|
||||||
|
* envelope emails. These appear in AWS SES bounce/complaint notifications (when
|
||||||
|
* "include original headers" is enabled) so an abusive send can be traced back
|
||||||
|
* to the originating Documenso user via the admin panel.
|
||||||
|
*
|
||||||
|
* Only opaque IDs are included so recipients cannot see the sender's email
|
||||||
|
* address or name in the delivered message source.
|
||||||
|
*/
|
||||||
|
export const buildEnvelopeEmailHeaders = ({
|
||||||
|
userId,
|
||||||
|
envelopeId,
|
||||||
|
teamId,
|
||||||
|
}: BuildEnvelopeEmailHeadersOptions): Record<string, string> => {
|
||||||
|
return {
|
||||||
|
'X-Documenso-Sender-User-Id': String(userId),
|
||||||
|
'X-Documenso-Envelope-Id': envelopeId,
|
||||||
|
'X-Documenso-Team-Id': String(teamId),
|
||||||
|
};
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user