diff --git a/overleafserver/EmailBuilder.js b/overleafserver/EmailBuilder.js
deleted file mode 100644
index d839d67..0000000
--- a/overleafserver/EmailBuilder.js
+++ /dev/null
@@ -1,964 +0,0 @@
-const _ = require('lodash')
-const settings = require('@overleaf/settings')
-const moment = require('moment')
-const EmailMessageHelper = require('./EmailMessageHelper')
-const StringHelper = require('../Helpers/StringHelper')
-const BaseWithHeaderEmailLayout = require('./Layouts/BaseWithHeaderEmailLayout')
-const SpamSafe = require('./SpamSafe')
-const ctaEmailBody = require('./Bodies/cta-email')
-const NoCTAEmailBody = require('./Bodies/NoCTAEmailBody')
-
-function _emailBodyPlainText(content, opts, ctaEmail) {
- let emailBody = `${content.greeting(opts, true)}`
- emailBody += `\r\n\r\n`
- emailBody += `${content.message(opts, true).join('\r\n\r\n')}`
-
- if (ctaEmail) {
- emailBody += `\r\n\r\n`
- emailBody += `${content.ctaText(opts, true)}: ${content.ctaURL(opts, true)}`
- }
-
- if (
- content.secondaryMessage(opts, true) &&
- content.secondaryMessage(opts, true).length > 0
- ) {
- emailBody += `\r\n\r\n`
- emailBody += `${content.secondaryMessage(opts, true).join('\r\n\r\n')}`
- }
-
- emailBody += `\r\n\r\n`
- emailBody += `Regards,\r\nThe ${settings.appName} Team - ${settings.siteUrl}`
-
- if (
- settings.email &&
- settings.email.template &&
- settings.email.template.customFooter
- ) {
- emailBody += `\r\n\r\n`
- emailBody += settings.email.template.customFooter
- }
-
- return emailBody
-}
-
-function ctaTemplate(content) {
- if (
- !content.ctaURL ||
- !content.ctaText ||
- !content.message ||
- !content.subject
- ) {
- throw new Error('missing required CTA email content')
- }
- if (!content.title) {
- content.title = () => {}
- }
- if (!content.greeting) {
- content.greeting = () => 'Hi,'
- }
- if (!content.secondaryMessage) {
- content.secondaryMessage = () => []
- }
- if (!content.gmailGoToAction) {
- content.gmailGoToAction = () => {}
- }
- return {
- subject(opts) {
- return content.subject(opts)
- },
- layout: BaseWithHeaderEmailLayout,
- plainTextTemplate(opts) {
- return _emailBodyPlainText(content, opts, true)
- },
- compiledTemplate(opts) {
- return ctaEmailBody({
- title: content.title(opts),
- greeting: content.greeting(opts),
- message: content.message(opts),
- secondaryMessage: content.secondaryMessage(opts),
- ctaText: content.ctaText(opts),
- ctaURL: content.ctaURL(opts),
- gmailGoToAction: content.gmailGoToAction(opts),
- StringHelper,
- })
- },
- }
-}
-
-function NoCTAEmailTemplate(content) {
- if (content.greeting == null) {
- content.greeting = () => 'Hi,'
- }
- if (!content.message) {
- throw new Error('missing message')
- }
- return {
- subject(opts) {
- return content.subject(opts)
- },
- layout: BaseWithHeaderEmailLayout,
- plainTextTemplate(opts) {
- return `\
-${content.greeting(opts)}
-
-${content.message(opts, true).join('\r\n\r\n')}
-
-Regards,
-The ${settings.appName} Team - ${settings.siteUrl}\
- `
- },
- compiledTemplate(opts) {
- return NoCTAEmailBody({
- title:
- typeof content.title === 'function' ? content.title(opts) : undefined,
- greeting: content.greeting(opts),
- highlightedText:
- typeof content.highlightedText === 'function'
- ? content.highlightedText(opts)
- : undefined,
- message: content.message(opts),
- StringHelper,
- })
- },
- }
-}
-
-function buildEmail(templateName, opts) {
- const template = templates[templateName]
- opts.siteUrl = settings.siteUrl
- opts.body = template.compiledTemplate(opts)
- return {
- subject: template.subject(opts),
- html: template.layout(opts),
- text: template.plainTextTemplate && template.plainTextTemplate(opts),
- }
-}
-
-const templates = {}
-
-templates.registered = ctaTemplate({
- subject() {
- return `Activate your ${settings.appName} Account`
- },
- message(opts) {
- return [
- `Congratulations, you've just had an account created for you on ${
- settings.appName
- } with the email address '${_.escape(opts.to)}'.`,
- 'Click here to set your password and log in:',
- ]
- },
- secondaryMessage() {
- return [
- `If you have any questions or problems, please contact ${settings.adminEmail}`,
- ]
- },
- ctaText() {
- return 'Set password'
- },
- ctaURL(opts) {
- return opts.setNewPasswordUrl
- },
-})
-
-templates.canceledSubscription = ctaTemplate({
- subject() {
- return `${settings.appName} thoughts`
- },
- message() {
- return [
- `We are sorry to see you cancelled your ${settings.appName} premium subscription. Would you mind giving us some feedback on what the site is lacking at the moment via this quick survey?`,
- ]
- },
- secondaryMessage() {
- return ['Thank you in advance!']
- },
- ctaText() {
- return 'Leave Feedback'
- },
- ctaURL(opts) {
- return 'https://docs.google.com/forms/d/e/1FAIpQLSfa7z_s-cucRRXm70N4jEcSbFsZeb0yuKThHGQL8ySEaQzF0Q/viewform?usp=sf_link'
- },
-})
-
-templates.reactivatedSubscription = ctaTemplate({
- subject() {
- return `Subscription Reactivated - ${settings.appName}`
- },
- message(opts) {
- return ['Your subscription was reactivated successfully.']
- },
- ctaText() {
- return 'View Subscription Dashboard'
- },
- ctaURL(opts) {
- return `${settings.siteUrl}/user/subscription`
- },
-})
-
-templates.passwordResetRequested = ctaTemplate({
- subject() {
- return `Password Reset - ${settings.appName}`
- },
- title() {
- return 'Password Reset'
- },
- message() {
- return [`We got a request to reset your ${settings.appName} password.`]
- },
- secondaryMessage() {
- return [
- "If you ignore this message, your password won't be changed.",
- "If you didn't request a password reset, let us know.",
- ]
- },
- ctaText() {
- return 'Reset password'
- },
- ctaURL(opts) {
- return opts.setNewPasswordUrl
- },
-})
-
-templates.confirmEmail = ctaTemplate({
- subject() {
- return `Confirm Email - ${settings.appName}`
- },
- title() {
- return 'Confirm Email'
- },
- message(opts) {
- return [
- `Please confirm that you have added a new email, ${opts.to}, to your ${settings.appName} account.`,
- ]
- },
- secondaryMessage() {
- return [
- `If you did not request this, please let us know at ${settings.adminEmail}.`,
- `If you have any questions or trouble confirming your email address, please get in touch with our support team at ${settings.adminEmail}.`,
- ]
- },
- ctaText() {
- return 'Confirm Email'
- },
- ctaURL(opts) {
- return opts.confirmEmailUrl
- },
-})
-
-templates.confirmCode = NoCTAEmailTemplate({
- greeting(opts) {
- return ''
- },
- subject(opts) {
- return `Confirm your email address on Overleaf (${opts.confirmCode})`
- },
- title(opts) {
- return 'Confirm your email address'
- },
- message(opts, isPlainText) {
- const msg = opts.isSecondary
- ? ['Use this 6-digit code to confirm your email address.']
- : [
- `Welcome to Overleaf! We're so glad you joined us.`,
- 'Use this 6-digit confirmation code to finish your setup.',
- ]
-
- if (isPlainText && opts.confirmCode) {
- msg.push(opts.confirmCode)
- }
- return msg
- },
- highlightedText(opts) {
- return opts.confirmCode
- },
-})
-
-templates.projectInvite = ctaTemplate({
- subject(opts) {
- const safeName = SpamSafe.isSafeProjectName(opts.project.name)
- const safeEmail = SpamSafe.isSafeEmail(opts.owner.email)
-
- if (safeName && safeEmail) {
- return `"${_.escape(opts.project.name)}" — shared by ${_.escape(
- opts.owner.email
- )}`
- }
- if (safeName) {
- return `${settings.appName} project shared with you — "${_.escape(
- opts.project.name
- )}"`
- }
- if (safeEmail) {
- return `${_.escape(opts.owner.email)} shared an ${
- settings.appName
- } project with you`
- }
-
- return `An ${settings.appName} project has been shared with you`
- },
- title(opts) {
- return 'Project Invite'
- },
- greeting(opts) {
- return ''
- },
- message(opts, isPlainText) {
- // build message depending on spam-safe variables
- const message = [`You have been invited to an ${settings.appName} project.`]
-
- if (SpamSafe.isSafeProjectName(opts.project.name)) {
- message.push('
Project:')
- message.push(`${_.escape(opts.project.name)}`)
- }
-
- if (SpamSafe.isSafeEmail(opts.owner.email)) {
- message.push(`
Shared by:`)
- message.push(`${_.escape(opts.owner.email)}`)
- }
-
- if (message.length === 1) {
- message.push('
Please view the project to find out more.')
- }
-
- return message.map(m => {
- return EmailMessageHelper.cleanHTML(m, isPlainText)
- })
- },
- ctaText() {
- return 'View project'
- },
- ctaURL(opts) {
- return opts.inviteUrl
- },
- gmailGoToAction(opts) {
- return {
- target: opts.inviteUrl,
- name: 'View project',
- description: `Join ${_.escape(
- SpamSafe.safeProjectName(opts.project.name, 'project')
- )} at ${settings.appName}`,
- }
- },
-})
-
-templates.reconfirmEmail = ctaTemplate({
- subject() {
- return `Reconfirm Email - ${settings.appName}`
- },
- title() {
- return 'Reconfirm Email'
- },
- message(opts) {
- return [
- `Please reconfirm your email address, ${opts.to}, on your ${settings.appName} account.`,
- ]
- },
- secondaryMessage() {
- return [
- 'If you did not request this, you can simply ignore this message.',
- `If you have any questions or trouble confirming your email address, please get in touch with our support team at ${settings.adminEmail}.`,
- ]
- },
- ctaText() {
- return 'Reconfirm Email'
- },
- ctaURL(opts) {
- return opts.confirmEmailUrl
- },
-})
-
-templates.verifyEmailToJoinTeam = ctaTemplate({
- subject(opts) {
- return `${opts.reminder ? 'Reminder: ' : ''}${_.escape(
- _formatUserNameAndEmail(opts.inviter, 'A collaborator')
- )} has invited you to join a group subscription on ${settings.appName}`
- },
- title(opts) {
- return `${opts.reminder ? 'Reminder: ' : ''}${_.escape(
- _formatUserNameAndEmail(opts.inviter, 'A collaborator')
- )} has invited you to join a group subscription on ${settings.appName}`
- },
- message(opts) {
- return [
- `Please click the button below to join the group subscription and enjoy the benefits of an upgraded ${settings.appName} account.`,
- ]
- },
- ctaText(opts) {
- return 'Join now'
- },
- ctaURL(opts) {
- return opts.acceptInviteUrl
- },
-})
-
-templates.verifyEmailToJoinManagedUsers = ctaTemplate({
- subject(opts) {
- return `${
- opts.reminder ? 'Reminder: ' : ''
- }You’ve been invited by ${_.escape(
- _formatUserNameAndEmail(opts.inviter, 'a collaborator')
- )} to join an ${settings.appName} group subscription.`
- },
- title(opts) {
- return `${
- opts.reminder ? 'Reminder: ' : ''
- }You’ve been invited by ${_.escape(
- _formatUserNameAndEmail(opts.inviter, 'a collaborator')
- )} to join an ${settings.appName} group subscription.`
- },
- message(opts) {
- return [
- `By joining this group, you'll have access to ${settings.appName} premium features such as additional collaborators, greater maximum compile time, and real-time track changes.`,
- ]
- },
- secondaryMessage(opts, isPlainText) {
- const changeProjectOwnerLink = EmailMessageHelper.displayLink(
- 'change project owner',
- `${settings.siteUrl}/learn/how-to/How_to_Transfer_Project_Ownership`,
- isPlainText
- )
-
- return [
- `User accounts in this group are managed by ${_.escape(
- _formatUserNameAndEmail(opts.admin, 'an admin')
- )}`,
- `If you accept, you’ll transfer the management of your ${settings.appName} account to the owner of the group subscription, who will then have admin rights over your account and control over your stuff.`,
- `If you have personal projects in your ${settings.appName} account that you want to keep separate, that’s not a problem. You can set up another account under a personal email address and change the ownership of your personal projects to the new account. Find out how to ${changeProjectOwnerLink}.`,
- ]
- },
- ctaURL(opts) {
- return opts.acceptInviteUrl
- },
- ctaText(opts) {
- return 'Accept invitation'
- },
- greeting() {
- return ''
- },
-})
-
-templates.inviteNewUserToJoinManagedUsers = ctaTemplate({
- subject(opts) {
- return `${
- opts.reminder ? 'Reminder: ' : ''
- }You’ve been invited by ${_.escape(
- _formatUserNameAndEmail(opts.inviter, 'a collaborator')
- )} to join an ${settings.appName} group subscription.`
- },
- title(opts) {
- return `${
- opts.reminder ? 'Reminder: ' : ''
- }You’ve been invited by ${_.escape(
- _formatUserNameAndEmail(opts.inviter, 'a collaborator')
- )} to join an ${settings.appName} group subscription.`
- },
- message(opts) {
- return ['']
- },
- secondaryMessage(opts) {
- return [
- `User accounts in this group are managed by ${_.escape(
- _formatUserNameAndEmail(opts.admin, 'an admin')
- )}.`,
- `If you accept, the owner of the group subscription will have admin rights over your account and control over your stuff.`,
- `What is ${settings.appName}?`,
- `${settings.appName} is the collaborative online LaTeX editor loved by researchers and technical writers. With thousands of ready-to-use templates and an array of LaTeX learning resources you’ll be up and running in no time.`,
- ]
- },
- ctaURL(opts) {
- return opts.acceptInviteUrl
- },
- ctaText(opts) {
- return 'Accept invitation'
- },
- greeting() {
- return ''
- },
-})
-
-templates.groupSSOLinkingInvite = ctaTemplate({
- subject(opts) {
- const subjectPrefix = opts.reminder ? 'Reminder: ' : 'Action required: '
- return `${subjectPrefix}Authenticate your Overleaf account`
- },
- title(opts) {
- const titlePrefix = opts.reminder ? 'Reminder: ' : ''
- return `${titlePrefix}Single sign-on enabled`
- },
- message(opts) {
- return [
- `Hi,
-