Просмотр исходного кода

Merge pull request #14252 from overleaf/mf-send-emails-surrendering-account

Send email to notify users to surrender their account to be managed in a managed users group environment

GitOrigin-RevId: 1f366a9ca1b5359844e288d33ee91097acb71c64
M Fahru 3 лет назад
Родитель
Сommit
a5ad8a1deb

+ 58 - 0
services/web/app/src/Features/Email/EmailBuilder.js

@@ -437,6 +437,64 @@ templates.inviteNewUserToJoinManagedUsers = ctaTemplate({
   },
 })
 
+templates.surrenderAccountForManagedUsers = ctaTemplate({
+  subject(opts) {
+    const admin = _.escape(_formatUserNameAndEmail(opts.admin, 'an admin'))
+
+    const toGroupName = opts.groupName ? ` to ${opts.groupName}` : ''
+
+    return `You’ve been invited by ${admin} to transfer management of your ${settings.appName} account${toGroupName}`
+  },
+  title(opts) {
+    const admin = _.escape(_formatUserNameAndEmail(opts.admin, 'an admin'))
+
+    const toGroupName = opts.groupName ? ` to ${opts.groupName}` : ''
+
+    return `You’ve been invited by ${admin} to transfer management of your ${settings.appName} account${toGroupName}`
+  },
+  message(opts, isPlainText) {
+    const admin = _.escape(_formatUserNameAndEmail(opts.admin, 'an admin'))
+
+    const groupName = opts.groupName ?? `a group managed by ${admin}`
+
+    // TODO update with actual wiki link once created
+    const managedUsersLink = EmailMessageHelper.displayLink(
+      'user account management',
+      `${settings.siteUrl}/learn/how-to/Managed_Users`,
+      isPlainText
+    )
+
+    return [
+      `Your ${settings.appName} account ${_.escape(
+        opts.to
+      )} is part of ${groupName} and your group administrator has now enabled ${managedUsersLink}. This will ensure that projects aren’t lost when someone leaves the group.`,
+    ]
+  },
+  secondaryMessage(opts, isPlainText) {
+    const transferProjectOwnershipLink = EmailMessageHelper.displayLink(
+      'change project owner',
+      `${settings.siteUrl}/learn/how-to/How_to_Transfer_Project_Ownership`,
+      isPlainText
+    )
+
+    return [
+      `<b>What does this mean for you?</b>`,
+      `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 ${transferProjectOwnershipLink}.`,
+      `If you think this invitation has been sent in error please contact your group administrator.`,
+    ]
+  },
+  ctaURL(opts) {
+    return opts.acceptInviteUrl
+  },
+  ctaText(opts) {
+    return 'Accept invitation'
+  },
+  greeting() {
+    return ''
+  },
+})
+
 templates.testEmail = ctaTemplate({
   subject() {
     return `A Test Email from ${settings.appName}`

+ 43 - 0
services/web/app/src/Features/Subscription/ManagedUsersHandler.js

@@ -10,6 +10,8 @@ const {
 } = require('../Errors/Errors')
 const UserGetter = require('../User/UserGetter')
 const UserUpdater = require('../User/UserUpdater')
+const EmailHandler = require('../Email/EmailHandler')
+const logger = require('@overleaf/logger')
 
 /**
  * This module contains functions for handling managed users in a
@@ -36,6 +38,8 @@ async function enableManagedUsers(subscriptionId) {
   // update the subscription to use the new policy
   subscription.groupPolicy = groupPolicy._id
   await subscription.save()
+
+  await _sendEmailToGroupMembers(subscriptionId)
 }
 
 /**
@@ -145,6 +149,45 @@ async function enrollInSubscription(userId, subscription) {
   }
 }
 
+/**
+ * Send email to all group members, irregardless of the member status.
+ * @async
+ * @function
+ * @param {string} subscriptionId - The ID of the subscription to enable
+ *   managed users for.
+ * @returns {Promise<void>} - A Promise that resolves when all the `sendEmail` function has been sent,
+ * irregardless of whether they're successful or failed.
+ */
+async function _sendEmailToGroupMembers(subscriptionId) {
+  const EMAIL_DELAY_IN_MS = 0
+
+  const subscription = await Subscription.findById(subscriptionId)
+    .populate('member_ids', 'email')
+    .populate('admin_id', ['first_name', 'last_name', 'email'])
+    .exec()
+
+  // On failure, log the error and carry on so that one email failing does not prevent other emails sending
+  for (const recipient of subscription.member_ids) {
+    try {
+      const opts = {
+        to: recipient.email,
+        admin: subscription.admin_id,
+        groupName: subscription.teamName,
+      }
+      EmailHandler.sendDeferredEmail(
+        'surrenderAccountForManagedUsers',
+        opts,
+        EMAIL_DELAY_IN_MS
+      )
+    } catch (err) {
+      logger.error(
+        { err, userId: recipient._id },
+        'could not send notification email to surrender account'
+      )
+    }
+  }
+}
+
 module.exports = {
   promises: {
     enableManagedUsers,