diff --git a/packages/component-user/index.js b/packages/component-user/index.js index 307f862c05b48216eedc7514a3a76bf38f06eb11..d48a221456d0a04ef43c702afd0e6b8b7a83ae31 100644 --- a/packages/component-user/index.js +++ b/packages/component-user/index.js @@ -1,10 +1,8 @@ const resolvers = require('./resolvers') const typeDefs = require('./typeDefs') -const model = require('./user') module.exports = { - model, - modelName: 'User', resolvers, typeDefs, + // modelName: 'User', } diff --git a/packages/component-user/notifications/emailCopy.js b/packages/component-user/notifications/emailCopy.js new file mode 100644 index 0000000000000000000000000000000000000000..b8c618a83b4b1a6cddea14520e5aa142adfc1cf4 --- /dev/null +++ b/packages/component-user/notifications/emailCopy.js @@ -0,0 +1,33 @@ +const config = require('config') + +const journalName = config.get('journal.name') +const getEmailCopy = ({ emailType, role }) => { + let paragraph + let hasIntro = true + let hasSignature = true + switch (emailType) { + case 'user-signup': + paragraph = `Thank you for creating an account on Hindawi’s review system. + To submit a manuscript and access your dashboard, please confirm your account by clicking on the link below.` + break + case 'user-added-by-admin': + hasIntro = false + hasSignature = false + paragraph = `You have been invited to join Hindawi as a ${role}. + Please confirm your account and set your account details by clicking on the link below.` + break + case 'he-added-by-admin': + paragraph = `You have been invited to become an Academic Editor for the journal ${journalName}. + To begin performing your editorial duties, you will need to create an account on Hindawi’s review system.<br/><br/> + Please confirm your account details by clicking on the link below.` + break + default: + throw new Error(`The ${emailType} email type is not defined.`) + } + + return { paragraph, hasLink: true, hasIntro, hasSignature } +} + +module.exports = { + getEmailCopy, +} diff --git a/packages/component-user/notifications/notification.js b/packages/component-user/notifications/notification.js new file mode 100644 index 0000000000000000000000000000000000000000..ddf2aeaa3a5a9784d2691f07ae5c6b8c2d497e86 --- /dev/null +++ b/packages/component-user/notifications/notification.js @@ -0,0 +1,58 @@ +const config = require('config') +const Email = require('@pubsweet/component-email-templating') +const { services } = require('pubsweet-component-helper-service') + +const { getEmailCopy } = require('./emailCopy') + +const { name: journalName, staffEmail } = config.get('journal') +const unsubscribeSlug = config.get('unsubscribe.url') + +class Notification { + constructor(user) { + this.user = user + } + + async notifyUserAddedByAdmin(role) { + const resetPath = config.get('invite-reset-password.url') + const { user } = this + const baseUrl = config.get('hostname') + const emailType = + role === 'Handling Editor' ? 'he-added-by-admin' : 'user-added-by-admin' + + const { paragraph, ...bodyProps } = getEmailCopy({ + role, + emailType, + }) + + const email = new Email({ + type: 'user', + fromEmail: `${journalName} <${staffEmail}>`, + toUser: { + email: user.email, + }, + content: { + subject: 'Confirm your account', + ctaLink: services.createUrl(baseUrl, resetPath, { + email: user.email, + token: user.accessTokens.passwordReset, + firstName: user.firstName, + lastName: user.lastName, + affiliation: user.affiliation, + title: user.title, + country: user.country, + }), + ctaText: 'CONFIRM ACCOUNT', + paragraph, + unsubscribeLink: services.createUrl(baseUrl, unsubscribeSlug, { + id: user.id, + token: user.accessTokens.unsubscribe, + }), + }, + bodyProps, + }) + + return email.sendEmail() + } +} + +module.exports = Notification diff --git a/packages/component-user/package.json b/packages/component-user/package.json new file mode 100644 index 0000000000000000000000000000000000000000..86aff30234d973a9ddc5a1b9bf4ce96ab39afc92 --- /dev/null +++ b/packages/component-user/package.json @@ -0,0 +1,42 @@ +{ + "name": "pubsweet-component-user", + "version": "0.0.1", + "description": "user component for faraday", + "license": "MIT", + "author": "Collaborative Knowledge Foundation", + "files": [ + "src" + ], + "main": "index.js", + "scripts": { + "test": "jest", + "docs": "./node_modules/.bin/apidoc -e \"(node_modules|public)\" -o public/apidoc", + "open-docs": "open public/apidoc/index.html" + }, + "repository": { + "type": "git", + "url": "https://gitlab.coko.foundation/xpub/xpub-faraday", + "path": "component-user" + }, + "dependencies": { + "chance": "^1.0.13" + }, + "peerDependencies": { + "@pubsweet/logger": "^0.0.1", + "pubsweet-component-helper-service": "0.0.1", + "@pubsweet/component-send-email": "0.2.4", + "pubsweet-server": "^10.0.0" + }, + "devDependencies": { + "apidoc": "^0.17.6", + "jest": "^22.1.1", + "supertest": "^3.0.0" + }, + "jest": { + "verbose": true, + "testRegex": "/src/.*.test.js$" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/component-user/resolvers.js b/packages/component-user/resolvers.js index 5cebc7e4c369fef7e606c74a9252c67e62e70aa7..3d04170be495a4dc67de8099d33d771c9ba3c10c 100644 --- a/packages/component-user/resolvers.js +++ b/packages/component-user/resolvers.js @@ -1,16 +1,24 @@ const Chance = require('chance') const { omit } = require('lodash') +const Notification = require('./notifications/notification') const chance = new Chance() const resolvers = { Mutation: { async addUserWithConfirmationEmail(_, { input }, ctx) { + const reqUser = await ctx.connectors.User.fetchOne(ctx.user, ctx) + if (!reqUser.admin) { + throw new Error('Unauthorized') + } + const roles = { admin: false, editorInChief: false, handlingEditor: false, } - roles[input.role] = true + if (input.role !== 'author') { + roles[input.role] = true + } input = { ...omit(input, ['role']), @@ -31,6 +39,9 @@ const resolvers = { try { const user = await ctx.connectors.User.create(input, ctx) + const notification = new Notification(user) + await notification.notifyUserAddedByAdmin(input.role) + return user } catch (e) { return e diff --git a/packages/xpub-faraday/config/components.json b/packages/xpub-faraday/config/components.json index 3083694230c19476ca18ffaac0a8d84ed7bf67e5..044b6a295a9bdb2f85b1fd4ad051fe37a8db7882 100644 --- a/packages/xpub-faraday/config/components.json +++ b/packages/xpub-faraday/config/components.json @@ -10,5 +10,6 @@ "pubsweet-component-email", "pubsweet-component-manuscript", "pubsweet-component-manuscript-manager", - "pubsweet-component-publons" + "pubsweet-component-publons", + "pubsweet-component-user" ] diff --git a/packages/xpub-faraday/config/default.js b/packages/xpub-faraday/config/default.js index a56d232c5df14e49c1bffa08de1ce55e0804543e..dff2f0db73f57fbf0b8023dce9a71a4f17ce0602 100644 --- a/packages/xpub-faraday/config/default.js +++ b/packages/xpub-faraday/config/default.js @@ -3,9 +3,7 @@ const path = require('path') const logger = require('winston') const components = require('./components.json') const journalConfig = require('../app/config/journal') -const { merge, get } = require('lodash') - -const users = require('../../component-user') +const { get } = require('lodash') const getDbConfig = () => { if (process.env.DATABASE) { @@ -48,8 +46,6 @@ module.exports = { secret: 'SECRET', enableExperimentalGraphql: true, graphiql: true, - typeDefs: `${users.typeDefs}`, - resolvers: merge({}, users.resolvers), }, 'pubsweet-client': { API_ENDPOINT: '/api', @@ -151,4 +147,5 @@ module.exports = { passwordStrengthRegex: new RegExp( '^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&,.?;\'*><)([}{}":`~+=_-\\|/])(?=.{6,128})', ), + hostname: process.env.HOSTNAME || 'http://localhost:3000', }