Skip to content

Commit 9aa2e58

Browse files
authored
Merge pull request #393 from captableinc/fix/replyto-and-sender-name
fix: replyTo and email from name
2 parents cb3addb + 61d9984 commit 9aa2e58

File tree

9 files changed

+53
-20
lines changed

9 files changed

+53
-20
lines changed

src/jobs/auth-verification-email.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,8 @@ export const sendAuthVerificationEmail = async (
1515
) => {
1616
const { email, token } = payload;
1717
const baseUrl = env.NEXT_PUBLIC_BASE_URL;
18-
1918
const confirmLink = `${baseUrl}/verify-email/${token}`;
2019

21-
console.log("Sending email to ", email, "with link ", confirmLink);
22-
2320
const html = await render(
2421
AccountVerificationEmail({
2522
verifyLink: confirmLink,

src/jobs/esign-confirmation-email.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export type ConfirmationEmailPayloadType = {
88
fileUrl: string;
99
documentName: string;
1010
senderName: string | null;
11+
senderEmail: string | null;
1112
company: {
1213
name: string;
1314
logo?: string | null;
@@ -23,11 +24,13 @@ export const sendEsignConfirmationEmail = async (
2324
documentName: payload.documentName,
2425
recipient: payload.recipient,
2526
senderName: payload.senderName,
27+
senderEmail: payload.senderEmail,
2628
company: payload.company,
2729
}),
2830
);
2931
await sendMail({
3032
to: payload.recipient.email,
33+
...(payload.senderEmail && { replyTo: payload.senderEmail }),
3134
subject: "Completed e-signed documents from all parties",
3235
html,
3336
attachments: [
@@ -36,6 +39,10 @@ export const sendEsignConfirmationEmail = async (
3639
path: payload.fileUrl,
3740
},
3841
],
42+
43+
headers: {
44+
"X-From-Name": payload.senderName || "Captable",
45+
},
3946
});
4047
};
4148

src/jobs/esign-email.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,23 @@ export type ExtendedEsignPayloadType = EsignEmailPayloadType &
3333
AdditionalPayloadType;
3434

3535
export const sendEsignEmail = async (payload: ExtendedEsignPayloadType) => {
36-
const { email, token, ...rest } = payload;
36+
const { email, token, sender, ...rest } = payload;
3737
const baseUrl = env.NEXT_PUBLIC_BASE_URL;
3838
const html = await render(
3939
EsignEmail({
4040
signingLink: `${baseUrl}/esign/${token}`,
41+
sender,
4142
...rest,
4243
}),
4344
);
4445
await sendMail({
4546
to: email,
46-
subject: "eSign Link",
47+
...(sender?.email && { replyTo: sender.email }),
48+
subject: "eSign Document Request",
4749
html,
50+
headers: {
51+
"X-From-Name": sender?.name || "Captable",
52+
},
4853
});
4954
};
5055

src/jobs/esign-pdf.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ export type EsignPdfPayloadType = {
3030
bucketKey: string;
3131
templateName: string;
3232
companyId: string;
33-
uploaderName: string;
3433
recipients: { email: string; name?: string | null }[];
34+
sender: { email: string; name?: string | null };
3535
};
3636

3737
export class EsignPdfJob extends BaseJob<EsignPdfPayloadType> {
@@ -47,7 +47,7 @@ export class EsignPdfJob extends BaseJob<EsignPdfPayloadType> {
4747
templateName,
4848
requestIp,
4949
userAgent,
50-
uploaderName,
50+
sender,
5151
templateId,
5252
recipients,
5353
company,
@@ -73,7 +73,7 @@ export class EsignPdfJob extends BaseJob<EsignPdfPayloadType> {
7373
requestIp,
7474
templateId,
7575
templateName,
76-
uploaderName,
76+
uploaderName: sender.name || "Captable",
7777
userAgent,
7878
});
7979
});
@@ -87,7 +87,8 @@ export class EsignPdfJob extends BaseJob<EsignPdfPayloadType> {
8787
documentName: templateName,
8888
recipient,
8989
company,
90-
senderName: uploaderName,
90+
senderName: sender.name || "Captable",
91+
senderEmail: sender.email as string,
9192
},
9293
}));
9394

src/jobs/share-data-room-email.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ export const sendShareDataRoomEmail = async (
3939
link,
4040
}),
4141
),
42+
43+
headers: {
44+
"X-From-Name": senderName,
45+
},
4246
});
4347
};
4448

src/jobs/share-update-email.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ export const sendShareUpdateEmail = async (payload: UpdateSharePayloadType) => {
3939
link,
4040
}),
4141
),
42+
43+
headers: {
44+
"X-From-Name": senderName,
45+
},
4246
});
4347
};
4448

src/server/mailer.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,21 @@ const getTransport = () => {
1212
});
1313
};
1414

15+
type RecordType = Record<string, string | undefined>;
16+
1517
export const sendMail = (options: Omit<SendMailOptions, "from">) => {
18+
let from = `Captable <${env.EMAIL_FROM}>`;
19+
const headers = (options.headers || {}) as RecordType;
20+
21+
const senderName = headers["X-From-Name"];
22+
23+
if (senderName) {
24+
from = `${senderName} <${env.EMAIL_FROM}>`;
25+
}
26+
1627
const transport = getTransport();
1728
return transport.sendMail({
18-
from: env.EMAIL_FROM,
29+
from,
1930
...options,
2031
});
2132
};

src/trpc/routers/document-router/procedures/create-document.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { generatePublicId } from "@/common/id";
22
import { Audit } from "@/server/audit";
33
import { checkMembership } from "@/server/auth";
4-
import { type TPrismaOrTransaction } from "@/server/db";
4+
import type { TPrismaOrTransaction } from "@/server/db";
55
import { withAuth, type withAuthTrpcContextType } from "@/trpc/api/trpc";
66
import {
77
type TypeZodCreateDocumentMutationSchema,

src/trpc/routers/template-router/procedures/sign-template.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export const signTemplateProcedure = withoutAuth
2828
const bucketKey = template.bucket.key;
2929
const companyId = template.companyId;
3030
const templateName = template.name;
31+
const sender = template.uploader.user;
3132

3233
const totalGroups = new Set(
3334
template.fields.map((item) => item.recipientId),
@@ -106,7 +107,9 @@ export const signTemplateProcedure = withoutAuth
106107
},
107108
});
108109

109-
const data = values.reduce<Record<string, string>>((prev, curr) => {
110+
const data: Record<string, string> = values.reduce<
111+
Record<string, string>
112+
>((prev, curr) => {
110113
prev[curr.id] = curr.prefilledValue ?? "";
111114

112115
return prev;
@@ -133,7 +136,6 @@ export const signTemplateProcedure = withoutAuth
133136
companyId,
134137
templateName,
135138
fields: template.fields,
136-
uploaderName: "Captable, Inc.",
137139
data,
138140
templateId: template.id,
139141
db: tx,
@@ -144,6 +146,8 @@ export const signTemplateProcedure = withoutAuth
144146
email: item.email,
145147
name: item.name,
146148
})),
149+
sender,
150+
uploaderName: sender.name || "Captable",
147151
});
148152
}
149153
} else {
@@ -168,19 +172,20 @@ export const signTemplateProcedure = withoutAuth
168172
companyId,
169173
templateName,
170174
fields: template.fields,
171-
uploaderName: recipient.name ?? "unknown signer",
172175
data: input.data,
173176
templateId: template.id,
174177
db: tx,
175178
requestIp,
176179
userAgent,
180+
sender,
177181
recipients: [
178182
{
179183
email: recipient.email,
180184
name: recipient.name,
181185
},
182186
],
183187
company: template.company,
188+
uploaderName: sender.name || "Captable",
184189
});
185190
}
186191

@@ -203,8 +208,6 @@ export const signTemplateProcedure = withoutAuth
203208
});
204209
const email = nextDelivery.email;
205210

206-
const uploaderName = template.uploader.user.name;
207-
208211
await EsignAudit.create(
209212
{
210213
action: "document.email.sent",
@@ -214,7 +217,7 @@ export const signTemplateProcedure = withoutAuth
214217
ip: ctx.requestIp,
215218
location: "",
216219
userAgent: ctx.userAgent,
217-
summary: `${uploaderName ? uploaderName : ""} sent "${
220+
summary: `${sender.name ? sender.name : ""} sent "${
218221
template.name
219222
}" to ${
220223
recipient.name ? recipient.name : ""
@@ -226,11 +229,11 @@ export const signTemplateProcedure = withoutAuth
226229
await new EsignNotificationEmailJob().emit({
227230
email,
228231
token,
232+
sender,
229233
message: template.message,
230234
documentName: template.name,
231235
recipient: nextDelivery,
232236
company: template.company,
233-
sender: template.uploader.user,
234237
});
235238
}
236239
}
@@ -248,6 +251,7 @@ interface TSignPdfOptions
248251
name: string;
249252
logo?: string | null;
250253
};
254+
sender: { name: string | null; email: string | null };
251255
recipients: { name: string | null; email: string }[];
252256
}
253257

@@ -260,7 +264,7 @@ async function signPdf({
260264
templateName,
261265
data,
262266
fields,
263-
uploaderName,
267+
sender,
264268
templateId,
265269
recipients,
266270
company,
@@ -277,9 +281,9 @@ async function signPdf({
277281
requestIp,
278282
templateId,
279283
templateName,
280-
uploaderName,
281284
userAgent,
282285
recipients,
286+
sender: sender as { email: string; name: string },
283287
company,
284288
},
285289
{ singletonKey: `esign-${templateId}`, useSingletonQueue: true },

0 commit comments

Comments
 (0)