diff --git a/packages/email/template-components/template-document-invite.tsx b/packages/email/template-components/template-document-invite.tsx index b99b1a1b4..644addb71 100644 --- a/packages/email/template-components/template-document-invite.tsx +++ b/packages/email/template-components/template-document-invite.tsx @@ -12,6 +12,8 @@ export interface TemplateDocumentInviteProps { assetBaseUrl: string; role: RecipientRole; selfSigner: boolean; + isTeamInvite: boolean; + teamName?: string; } export const TemplateDocumentInvite = ({ @@ -21,6 +23,8 @@ export const TemplateDocumentInvite = ({ assetBaseUrl, role, selfSigner, + isTeamInvite, + teamName, }: TemplateDocumentInviteProps) => { const { actionVerb, progressiveVerb } = RECIPIENT_ROLES_DESCRIPTION[role]; @@ -36,6 +40,12 @@ export const TemplateDocumentInvite = ({
{`"${documentName}"`} + ) : isTeamInvite ? ( + <> + {`${inviterName} on behalf of ${teamName} has invited you to ${actionVerb.toLowerCase()}`} +
+ {`"${documentName}"`} + ) : ( <> {`${inviterName} has invited you to ${actionVerb.toLowerCase()}`} diff --git a/packages/email/templates/document-invite.tsx b/packages/email/templates/document-invite.tsx index 52a40d804..7e845126b 100644 --- a/packages/email/templates/document-invite.tsx +++ b/packages/email/templates/document-invite.tsx @@ -23,6 +23,9 @@ export type DocumentInviteEmailTemplateProps = Partial { const action = RECIPIENT_ROLES_DESCRIPTION[role].actionVerb.toLowerCase(); const previewText = selfSigner ? `Please ${action} your document ${documentName}` + : isTeamInvite + ? `${inviterName} on behalf of ${teamName} has invited you to ${action} ${documentName}` : `${inviterName} has invited you to ${action} ${documentName}`; const getAssetUrl = (path: string) => { @@ -76,6 +83,8 @@ export const DocumentInviteEmailTemplate = ({ assetBaseUrl={assetBaseUrl} role={role} selfSigner={selfSigner} + isTeamInvite={isTeamInvite} + teamName={teamName} /> diff --git a/packages/lib/jobs/definitions/emails/send-signing-email.ts b/packages/lib/jobs/definitions/emails/send-signing-email.ts index 0244df34f..43ad730c6 100644 --- a/packages/lib/jobs/definitions/emails/send-signing-email.ts +++ b/packages/lib/jobs/definitions/emails/send-signing-email.ts @@ -58,6 +58,12 @@ export const SEND_SIGNING_EMAIL_JOB_DEFINITION = { }, include: { documentMeta: true, + team: { + select: { + teamEmail: true, + name: true, + }, + }, }, }), prisma.recipient.findFirstOrThrow({ @@ -67,7 +73,7 @@ export const SEND_SIGNING_EMAIL_JOB_DEFINITION = { }), ]); - const { documentMeta } = document; + const { documentMeta, team } = document; if (recipient.role === RecipientRole.CC) { return; @@ -75,6 +81,7 @@ export const SEND_SIGNING_EMAIL_JOB_DEFINITION = { const customEmail = document?.documentMeta; const isDirectTemplate = document.source === DocumentSource.TEMPLATE_DIRECT_LINK; + const isTeamDocument = document.teamId !== null; const recipientEmailType = RECIPIENT_ROLE_TO_EMAIL_TYPE[recipient.role]; @@ -96,6 +103,11 @@ export const SEND_SIGNING_EMAIL_JOB_DEFINITION = { emailSubject = `Please ${recipientActionVerb} this document created by your direct template`; } + if (isTeamDocument && team) { + emailSubject = `${team.name} invited you to ${recipientActionVerb} a document`; + emailMessage = `${user.name} on behalf of ${team.name} has invited you to ${recipientActionVerb} the document "${document.title}".`; + } + const customEmailTemplate = { 'signer.name': name, 'signer.email': email, @@ -108,12 +120,15 @@ export const SEND_SIGNING_EMAIL_JOB_DEFINITION = { const template = createElement(DocumentInviteEmailTemplate, { documentName: document.title, inviterName: user.name || undefined, - inviterEmail: user.email, + inviterEmail: isTeamDocument ? team?.teamEmail?.email || user.email : user.email, assetBaseUrl, signDocumentLink, customBody: renderCustomEmailTemplate(emailMessage, customEmailTemplate), role: recipient.role, selfSigner, + isTeamInvite: isTeamDocument, + teamName: team?.name, + teamEmail: team?.teamEmail?.email, }); await io.runTask('send-signing-email', async () => { diff --git a/packages/prisma/seed/initial-seed.ts b/packages/prisma/seed/initial-seed.ts index 66c944c9b..649c64f5e 100644 --- a/packages/prisma/seed/initial-seed.ts +++ b/packages/prisma/seed/initial-seed.ts @@ -4,7 +4,7 @@ import path from 'node:path'; import { hashSync } from '@documenso/lib/server-only/auth/hash'; import { prisma } from '..'; -import { DocumentDataType, DocumentSource, Role } from '../client'; +import { DocumentDataType, DocumentSource, Role, TeamMemberRole } from '../client'; export const seedDatabase = async () => { const examplePdf = fs @@ -67,4 +67,64 @@ export const seedDatabase = async () => { }, }, }); + + const testUsers = [ + 'test@documenso.com', + 'test2@documenso.com', + 'test3@documenso.com', + 'test4@documenso.com', + ]; + + const createdUsers = []; + + for (const email of testUsers) { + const testUser = await prisma.user.upsert({ + where: { + email: email, + }, + create: { + name: 'Test User', + email: email, + emailVerified: new Date(), + password: hashSync('password'), + roles: [Role.USER], + }, + update: {}, + }); + + createdUsers.push(testUser); + } + + const team1 = await prisma.team.create({ + data: { + name: 'Team 1', + url: 'team1', + ownerUserId: createdUsers[0].id, + }, + }); + + const team2 = await prisma.team.create({ + data: { + name: 'Team 2', + url: 'team2', + ownerUserId: createdUsers[1].id, + }, + }); + + for (const team of [team1, team2]) { + await prisma.teamMember.createMany({ + data: [ + { + teamId: team.id, + userId: createdUsers[1].id, + role: TeamMemberRole.MEMBER, + }, + { + teamId: team.id, + userId: createdUsers[2].id, + role: TeamMemberRole.MEMBER, + }, + ], + }); + } };