2021-10-25 13:05:21 +00:00
|
|
|
import { TFunction } from "next-i18next";
|
2021-08-19 12:27:01 +00:00
|
|
|
import nodemailer from "nodemailer";
|
2021-06-05 22:53:33 +00:00
|
|
|
|
2021-10-25 13:05:21 +00:00
|
|
|
import { getErrorFromUnknown } from "@lib/errors";
|
|
|
|
|
2021-09-22 19:52:38 +00:00
|
|
|
import { serverConfig } from "../serverConfig";
|
|
|
|
|
2021-10-07 08:47:33 +00:00
|
|
|
export type Invitation = {
|
2021-10-25 13:05:21 +00:00
|
|
|
language: TFunction;
|
2021-10-07 08:47:33 +00:00
|
|
|
from?: string;
|
|
|
|
toEmail: string;
|
|
|
|
teamName: string;
|
|
|
|
token?: string;
|
|
|
|
};
|
|
|
|
|
|
|
|
type EmailProvider = {
|
|
|
|
from: string;
|
|
|
|
transport: any;
|
|
|
|
};
|
|
|
|
|
|
|
|
export function createInvitationEmail(data: Invitation) {
|
|
|
|
const provider = {
|
|
|
|
transport: serverConfig.transport,
|
|
|
|
from: serverConfig.from,
|
|
|
|
} as EmailProvider;
|
|
|
|
return sendEmail(data, provider);
|
2021-06-05 22:53:33 +00:00
|
|
|
}
|
|
|
|
|
2021-10-07 08:47:33 +00:00
|
|
|
const sendEmail = (invitation: Invitation, provider: EmailProvider): Promise<void> =>
|
2021-08-19 12:27:01 +00:00
|
|
|
new Promise((resolve, reject) => {
|
|
|
|
const { transport, from } = provider;
|
2021-06-05 22:53:33 +00:00
|
|
|
|
2021-10-25 13:05:21 +00:00
|
|
|
const { language: t } = invitation;
|
2021-10-07 08:47:33 +00:00
|
|
|
const invitationHtml = html(invitation);
|
2021-08-19 12:27:01 +00:00
|
|
|
nodemailer.createTransport(transport).sendMail(
|
|
|
|
{
|
2021-09-21 09:59:34 +00:00
|
|
|
from: `Cal.com <${from}>`,
|
2021-08-19 12:27:01 +00:00
|
|
|
to: invitation.toEmail,
|
2021-10-25 13:05:21 +00:00
|
|
|
subject: invitation.from
|
|
|
|
? t("user_invited_you", { user: invitation.from, teamName: invitation.teamName })
|
|
|
|
: t("you_have_been_invited", { teamName: invitation.teamName }),
|
2021-10-07 08:47:33 +00:00
|
|
|
html: invitationHtml,
|
|
|
|
text: text(invitationHtml),
|
2021-08-19 12:27:01 +00:00
|
|
|
},
|
2021-10-25 13:05:21 +00:00
|
|
|
(_err) => {
|
|
|
|
if (_err) {
|
|
|
|
const err = getErrorFromUnknown(_err);
|
|
|
|
console.error("SEND_INVITATION_NOTIFICATION_ERROR", invitation.toEmail, err);
|
|
|
|
reject(err);
|
|
|
|
return;
|
2021-08-19 12:27:01 +00:00
|
|
|
}
|
|
|
|
return resolve();
|
2021-06-05 22:53:33 +00:00
|
|
|
}
|
2021-08-19 12:27:01 +00:00
|
|
|
);
|
|
|
|
});
|
2021-06-05 22:53:33 +00:00
|
|
|
|
2021-10-07 08:47:33 +00:00
|
|
|
export function html(invitation: Invitation): string {
|
2021-10-25 13:05:21 +00:00
|
|
|
const { language: t } = invitation;
|
2021-06-09 21:29:31 +00:00
|
|
|
let url: string = process.env.BASE_URL + "/settings/teams";
|
|
|
|
if (invitation.token) {
|
|
|
|
url = `${process.env.BASE_URL}/auth/signup?token=${invitation.token}&callbackUrl=${url}`;
|
|
|
|
}
|
|
|
|
|
2021-08-19 12:27:01 +00:00
|
|
|
return (
|
|
|
|
`
|
2021-06-09 21:29:31 +00:00
|
|
|
<table style="width: 100%;">
|
|
|
|
<tr>
|
2021-06-05 22:53:33 +00:00
|
|
|
<td>
|
2021-06-09 21:29:31 +00:00
|
|
|
<center>
|
|
|
|
<table style="width: 640px; border: 1px solid gray; padding: 15px; margin: 0 auto; text-align: left;">
|
|
|
|
<tr>
|
2021-06-05 22:53:33 +00:00
|
|
|
<td>
|
2021-10-25 13:05:21 +00:00
|
|
|
${t("hi")},<br />
|
2021-06-09 21:29:31 +00:00
|
|
|
<br />` +
|
2021-10-25 13:05:21 +00:00
|
|
|
(invitation.from
|
|
|
|
? t("user_invited_you", { user: invitation.from, teamName: invitation.teamName })
|
|
|
|
: t("you_have_been_invited", { teamName: invitation.teamName })) +
|
|
|
|
`<br />
|
2021-06-09 21:29:31 +00:00
|
|
|
<br />
|
|
|
|
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-collapse:separate;line-height:100%;">
|
|
|
|
<tr>
|
|
|
|
<td>
|
|
|
|
<div>
|
|
|
|
<!--[if mso]>
|
|
|
|
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="${url}" style="height:40px;v-text-anchor:middle;width:130px;" arcsize="5%" strokecolor="#19cca3" fillcolor="#19cca3;width: 130;">
|
|
|
|
<w:anchorlock/>
|
|
|
|
<center style="color:#ffffff;font-family:Helvetica, sans-serif;font-size:18px; font-weight: 600;">Join team</center>
|
|
|
|
</v:roundrect>
|
|
|
|
<![endif]-->
|
2021-10-25 13:05:21 +00:00
|
|
|
<a href="${url}" style="display: inline-block; mso-hide:all; background-color: #19cca3; color: #FFFFFF; border:1px solid #19cca3; border-radius: 6px; line-height: 220%; width: 200px; font-family: Helvetica, sans-serif; font-size:18px; font-weight:600; text-align: center; text-decoration: none; -webkit-text-size-adjust:none; " target="_blank">${t(
|
|
|
|
"join_team"
|
|
|
|
)}</a>
|
2021-06-09 21:29:31 +00:00
|
|
|
</a>
|
|
|
|
</div>
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
</table><br />
|
2021-10-25 13:05:21 +00:00
|
|
|
${t("request_another_invitation_email", { toEmail: invitation.toEmail })}
|
2021-06-09 21:29:31 +00:00
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
</table>
|
|
|
|
</center>
|
|
|
|
</td>
|
2021-06-05 22:53:33 +00:00
|
|
|
</tr>
|
|
|
|
</table>
|
2021-08-19 12:27:01 +00:00
|
|
|
`
|
|
|
|
);
|
2021-10-07 08:47:33 +00:00
|
|
|
}
|
2021-06-05 22:53:33 +00:00
|
|
|
|
|
|
|
// just strip all HTML and convert <br /> to \n
|
2021-10-07 08:47:33 +00:00
|
|
|
export function text(htmlStr: string): string {
|
|
|
|
return htmlStr.replace("<br />", "\n").replace(/<[^>]+>/g, "");
|
|
|
|
}
|