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