From 1edb05e1ad14b94aa9b52d48162b02b1f3bb7abc Mon Sep 17 00:00:00 2001
From: Alexandru Munteanu <alexandru.munt@gmail.com>
Date: Tue, 17 Jul 2018 10:48:15 +0300
Subject: [PATCH] feat(email-notifications): change user schema

---
 .../src/services/User.js                      |  6 ++++++
 packages/component-mail-service/src/Mail.js   | 21 ++++++++++++++++---
 .../src/helpers/helpers.js                    |  8 +++----
 .../src/templates/partials/footer.hbs         |  2 +-
 packages/component-user-manager/src/Users.js  | 14 +++++++++----
 .../users/{subscriptions.js => subscribe.js}  |  7 ++++---
 .../src/components/Admin/utils.js             |  6 ++++++
 .../components/UserProfile/UserProfilePage.js |  2 +-
 .../components-faraday/src/redux/users.js     |  9 +++-----
 packages/xpub-faraday/config/default.js       |  3 +++
 packages/xpub-faraday/config/validations.js   |  7 ++++++-
 11 files changed, 62 insertions(+), 23 deletions(-)
 rename packages/component-user-manager/src/routes/users/{subscriptions.js => subscribe.js} (73%)

diff --git a/packages/component-helper-service/src/services/User.js b/packages/component-helper-service/src/services/User.js
index 97821f164..39ad3356c 100644
--- a/packages/component-helper-service/src/services/User.js
+++ b/packages/component-helper-service/src/services/User.js
@@ -28,6 +28,12 @@ class User {
       handlingEditor: role === 'handlingEditor',
       invitationToken: role === 'reviewer' ? uuid.v4() : '',
       isActive: true,
+      notifications: {
+        email: {
+          system: true,
+          user: true,
+        },
+      },
     }
 
     let newUser = new UserModel(userBody)
diff --git a/packages/component-mail-service/src/Mail.js b/packages/component-mail-service/src/Mail.js
index cb3181bd2..0c8c9319d 100644
--- a/packages/component-mail-service/src/Mail.js
+++ b/packages/component-mail-service/src/Mail.js
@@ -6,6 +6,7 @@ const confirmSignUp = config.get('confirm-signup.url')
 const resetPath = config.get('invite-reset-password.url')
 const resetPasswordPath = config.get('invite-reviewer.url')
 const forgotPath = config.get('forgot-password.url')
+const unsubscribeSlug = config.get('unsubscribe.url')
 
 module.exports = {
   sendSimpleEmail: async ({
@@ -18,6 +19,13 @@ module.exports = {
     let subject, textBody
     let emailTemplate = 'simpleCTA'
     const replacements = {}
+    replacements.unsubscribeLink = helpers.createUrl(
+      dashboardUrl,
+      unsubscribeSlug,
+      {
+        id: user.id,
+      },
+    )
     switch (emailType) {
       case 'assign-handling-editor':
         subject = 'Hindawi Handling Editor Invitation'
@@ -28,6 +36,7 @@ module.exports = {
         replacements.previewText = 'An Editor in Chief has assigned you'
         replacements.buttonText = 'VIEW DASHBOARD'
         replacements.url = dashboardUrl
+
         textBody = `${replacements.headline} ${replacements.paragraph} ${
           replacements.url
         } ${replacements.buttonText}`
@@ -236,6 +245,9 @@ module.exports = {
       previewText: 'invitation from Hindawi',
       intro: `Dear ${user.firstName} ${user.lastName}`,
       manuscriptText: '',
+      unsubscribeLink: helpers.createUrl(baseUrl, unsubscribeSlug, {
+        id: user.id,
+      }),
     }
     let textBody
     switch (emailType) {
@@ -306,8 +318,8 @@ module.exports = {
     return Email.send(mailData)
   },
   sendNotificationEmail: async ({
-    toEmail,
     user,
+    toEmail,
     emailType,
     meta = { privateNote: '' },
   }) => {
@@ -324,9 +336,12 @@ module.exports = {
       : ''
     const replacements = {
       detailsUrl,
-      beforeAnchor: '',
-      afterAnchor: '',
       hasLink: true,
+      afterAnchor: '',
+      beforeAnchor: '',
+      unsubscribeLink: helpers.createUrl(meta.baseUrl, unsubscribeSlug, {
+        id: user.id,
+      }),
     }
     switch (emailType) {
       case 'unassign-reviewer':
diff --git a/packages/component-mail-service/src/helpers/helpers.js b/packages/component-mail-service/src/helpers/helpers.js
index 6f6a01f11..12b4dafae 100644
--- a/packages/component-mail-service/src/helpers/helpers.js
+++ b/packages/component-mail-service/src/helpers/helpers.js
@@ -9,7 +9,7 @@ const createUrl = (baseUrl, slug, queryParams = null) =>
 
 const getEmailBody = (emailType, replacements) => {
   handlePartial('header', replacements)
-  handlePartial('footer')
+  handlePartial('footer', replacements)
   handlePartial('mainButton', replacements)
   handlePartial('mainBody', replacements)
 
@@ -18,7 +18,7 @@ const getEmailBody = (emailType, replacements) => {
 
 const getNotificationBody = (emailType, replacements) => {
   handlePartial('notificationHeader', replacements)
-  handlePartial('footer')
+  handlePartial('footer', replacements)
   handlePartial('signature', replacements)
   if (replacements.detailsUrl !== undefined)
     handlePartial('manuscriptDetailsLink', replacements)
@@ -29,7 +29,7 @@ const getNotificationBody = (emailType, replacements) => {
 
 const getInvitationBody = (emailType, replacements) => {
   handlePartial('invitationHeader', replacements)
-  handlePartial('footer')
+  handlePartial('footer', replacements)
   handlePartial('invitationUpperContent', replacements)
   handlePartial('invitationButtons', replacements)
   handlePartial('manuscriptData', replacements)
@@ -117,10 +117,10 @@ const getExpectedDate = (timestamp, daysExpected) => {
 }
 
 module.exports = {
+  getBody,
   createUrl,
   getEmailBody,
   getExpectedDate,
   getNotificationBody,
   getInvitationBody,
-  getBody,
 }
diff --git a/packages/component-mail-service/src/templates/partials/footer.hbs b/packages/component-mail-service/src/templates/partials/footer.hbs
index 4b93ccf59..355088275 100644
--- a/packages/component-mail-service/src/templates/partials/footer.hbs
+++ b/packages/component-mail-service/src/templates/partials/footer.hbs
@@ -10,7 +10,7 @@
     </p>
   </div>
   <p style="font-family:Arial, Helvetica, sans-serif;font-size:12px;line-height:20px">
-    <a class="Unsubscribe--unsubscribeLink" href="[Unsubscribe]">Unsubscribe</a>
+    <a class="Unsubscribe--unsubscribeLink" href="{{ unsubscribeLink }}">Unsubscribe</a>
   </p>
 </div>
 </td>
diff --git a/packages/component-user-manager/src/Users.js b/packages/component-user-manager/src/Users.js
index bae6f9efd..38c401699 100644
--- a/packages/component-user-manager/src/Users.js
+++ b/packages/component-user-manager/src/Users.js
@@ -130,7 +130,8 @@ const Users = app => {
    * @apiGroup Users
    * @apiParamExample {json} Body
    *    {
-   *      "isUnsubscribed": true,
+   *      "id": "a6184463-b17a-42f8-b02b-ae1d755cdc6b",
+   *      "subscribe": true,
    *    }
    * @apiSuccessExample {json} Success
    *    HTTP/1.1 200 OK
@@ -146,15 +147,20 @@ const Users = app => {
    *      "isConfirmed": true,
    *      "editorInChief": false,
    *      "handlingEditor": false,
-   *      "isUnsubscribed": true
+   *      "notifications": {
+   *        "email": {
+   *           "system": true,
+   *           "user": true
+   *         }
+   *       }
    *    }
    * @apiErrorExample {json} Reset password errors
    *    HTTP/1.1 400 Bad Request
    *    HTTP/1.1 404 Not Found
    */
   app.patch(
-    '/api/users/subscriptions',
-    require('./routes/users/subscriptions')(app.locals.models),
+    '/api/users/subscribe',
+    require('./routes/users/subscribe')(app.locals.models),
   )
 
   // register ORCID authentication strategy
diff --git a/packages/component-user-manager/src/routes/users/subscriptions.js b/packages/component-user-manager/src/routes/users/subscribe.js
similarity index 73%
rename from packages/component-user-manager/src/routes/users/subscriptions.js
rename to packages/component-user-manager/src/routes/users/subscribe.js
index eb0aa8eaa..fa90c8481 100644
--- a/packages/component-user-manager/src/routes/users/subscriptions.js
+++ b/packages/component-user-manager/src/routes/users/subscribe.js
@@ -1,15 +1,16 @@
+const { set } = require('lodash')
 const { services } = require('pubsweet-component-helper-service')
 
 module.exports = models => async (req, res) => {
-  const { isUnsubscribed, id } = req.body
+  const { subscribe, id } = req.body
 
-  if (!services.checkForUndefinedParams(isUnsubscribed, id))
+  if (!services.checkForUndefinedParams(subscribe, id))
     return res.status(400).json({ error: 'Missing required params.' })
 
   let user
   try {
     user = await models.User.find(id)
-    user.isUnsubscribed = isUnsubscribed
+    set(user, 'notifications.email.user', subscribe)
     user = await user.save()
 
     return res.status(200).json({ user })
diff --git a/packages/components-faraday/src/components/Admin/utils.js b/packages/components-faraday/src/components/Admin/utils.js
index 99934cd10..2cb2c8023 100644
--- a/packages/components-faraday/src/components/Admin/utils.js
+++ b/packages/components-faraday/src/components/Admin/utils.js
@@ -31,6 +31,12 @@ export const setAdmin = values => {
     password: 'defaultpass',
     editorInChief: newValues.role === 'editorInChief',
     handlingEditor: newValues.role === 'handlingEditor',
+    notifications: {
+      email: {
+        system: true,
+        user: true,
+      },
+    },
   }
 }
 
diff --git a/packages/components-faraday/src/components/UserProfile/UserProfilePage.js b/packages/components-faraday/src/components/UserProfile/UserProfilePage.js
index 8c95565d6..7e4e7cbd7 100644
--- a/packages/components-faraday/src/components/UserProfile/UserProfilePage.js
+++ b/packages/components-faraday/src/components/UserProfile/UserProfilePage.js
@@ -23,7 +23,7 @@ const UserProfilePage = ({ history, user, changeEmailSubscription }) => (
     <AccountDetails history={history} user={user} />
     <EmailNotifications
       changeEmailSubscription={changeEmailSubscription}
-      subscribed={!get(user, 'isUnsubscribed')}
+      subscribed={get(user, 'notifications.email.user')}
       userId={get(user, 'id')}
     />
     <LinkOrcID id={get(user, 'id')} orcid={get(user, 'orcid')} />
diff --git a/packages/components-faraday/src/redux/users.js b/packages/components-faraday/src/redux/users.js
index 0d530761b..d988ba299 100644
--- a/packages/components-faraday/src/redux/users.js
+++ b/packages/components-faraday/src/redux/users.js
@@ -22,12 +22,9 @@ export const confirmUser = (userId, confirmationToken) => dispatch =>
     return dispatch(loginSuccess(user))
   })
 
-export const changeEmailSubscription = (
-  id,
-  isUnsubscribed = false,
-) => dispatch => {
-  update(`/users/subscriptions`, {
+export const changeEmailSubscription = (id, subscribe = true) => dispatch => {
+  update(`/users/subscribe`, {
     id,
-    isUnsubscribed,
+    subscribe,
   }).then(() => dispatch(actions.getCurrentUser()))
 }
diff --git a/packages/xpub-faraday/config/default.js b/packages/xpub-faraday/config/default.js
index 37367502a..22d48a7d7 100644
--- a/packages/xpub-faraday/config/default.js
+++ b/packages/xpub-faraday/config/default.js
@@ -83,6 +83,9 @@ module.exports = {
   'confirm-signup': {
     url: process.env.PUBSWEET_CONFIRM_SIGNUP_URL || '/confirm-signup',
   },
+  unsubscribe: {
+    url: process.env.PUBSWEET_UNSUBSCRIBE_URL || '/unsubscribe',
+  },
   roles: {
     global: ['admin', 'editorInChief', 'author', 'handlingEditor'],
     collection: ['handlingEditor', 'reviewer', 'author'],
diff --git a/packages/xpub-faraday/config/validations.js b/packages/xpub-faraday/config/validations.js
index f8ca55e07..c9e88be1e 100644
--- a/packages/xpub-faraday/config/validations.js
+++ b/packages/xpub-faraday/config/validations.js
@@ -131,7 +131,12 @@ module.exports = {
     confirmationToken: Joi.string().allow(''),
     agreeTC: Joi.boolean(),
     isActive: Joi.boolean().default(true),
-    isUnsubscribed: Joi.boolean(),
+    notifications: Joi.object({
+      email: Joi.object({
+        system: Joi.boolean().default(true),
+        user: Joi.boolean().default(true),
+      }),
+    }),
   },
   team: {
     group: Joi.string(),
-- 
GitLab