From a120374a6bdfb7fea7ab061c419a3650445f3c18 Mon Sep 17 00:00:00 2001 From: d34thwings Date: Fri, 15 Feb 2019 14:04:58 +0000 Subject: [PATCH] feat(hooks): Better hook triggers informations --- .../api/src/apps/routes/deleteApp.route.js | 2 +- packages/api/src/apps/routes/getApp.route.js | 2 +- packages/api/src/apps/routes/getApps.route.js | 2 +- packages/api/src/apps/routes/postApp.route.js | 2 +- packages/api/src/apps/routes/putApp.route.js | 2 +- .../api/src/hooks/routes/deleteHook.route.js | 2 +- .../api/src/hooks/routes/getHook.route.js | 2 +- .../api/src/hooks/routes/getHooks.route.js | 2 +- .../api/src/hooks/routes/postHook.route.js | 2 +- .../api/src/hooks/routes/putHook.route.js | 2 +- packages/api/src/middlewares.js | 2 +- packages/api/src/users/models/user.model.js | 4 +- packages/api/src/users/routes/cget-users.js | 2 +- packages/api/src/users/routes/delete-users.js | 11 ++--- packages/api/src/users/routes/get-me.js | 2 +- packages/api/src/users/routes/get-users.js | 2 +- packages/api/src/users/routes/post-users.js | 2 +- packages/api/src/users/routes/put-users.js | 42 ++++++++++--------- .../api/src/users/routes/user-validation.js | 16 +++---- .../app/modules/auth/pages/login.page.jsx | 3 +- 20 files changed, 56 insertions(+), 50 deletions(-) diff --git a/packages/api/src/apps/routes/deleteApp.route.js b/packages/api/src/apps/routes/deleteApp.route.js index 822840b..9369e23 100644 --- a/packages/api/src/apps/routes/deleteApp.route.js +++ b/packages/api/src/apps/routes/deleteApp.route.js @@ -8,7 +8,7 @@ module.exports = { method: 'DELETE', path: '/apps/{app}', config: { - pre: [hasScopeInList('apps:delete'), hasRoleInList(permissions.deleteApp)], + pre: [hasScopeInList(['apps:delete']), hasRoleInList(permissions.deleteApp)], validate: { params, }, diff --git a/packages/api/src/apps/routes/getApp.route.js b/packages/api/src/apps/routes/getApp.route.js index b26e742..6da084a 100644 --- a/packages/api/src/apps/routes/getApp.route.js +++ b/packages/api/src/apps/routes/getApp.route.js @@ -7,7 +7,7 @@ module.exports = { method: 'GET', path: '/apps/{app}', config: { - pre: [hasScopeInList('apps:get')], + pre: [hasScopeInList(['apps:get'])], validate: { params, }, diff --git a/packages/api/src/apps/routes/getApps.route.js b/packages/api/src/apps/routes/getApps.route.js index 9530d55..687430a 100644 --- a/packages/api/src/apps/routes/getApps.route.js +++ b/packages/api/src/apps/routes/getApps.route.js @@ -5,7 +5,7 @@ module.exports = { method: 'GET', path: '/apps', config: { - pre: [hasScopeInList('apps:get')], + pre: [hasScopeInList(['apps:get'])], validate: { query: Joi.object().keys({ name: Joi.string().max(50), diff --git a/packages/api/src/apps/routes/postApp.route.js b/packages/api/src/apps/routes/postApp.route.js index b7546ed..4bd3a4a 100644 --- a/packages/api/src/apps/routes/postApp.route.js +++ b/packages/api/src/apps/routes/postApp.route.js @@ -7,7 +7,7 @@ module.exports = { method: 'POST', path: '/apps', config: { - pre: [hasScopeInList('apps:create'), hasRoleInList(permissions.addApp)], + pre: [hasScopeInList(['apps:create']), hasRoleInList(permissions.addApp)], validate: { payload, }, diff --git a/packages/api/src/apps/routes/putApp.route.js b/packages/api/src/apps/routes/putApp.route.js index abdd5ad..778a6f9 100644 --- a/packages/api/src/apps/routes/putApp.route.js +++ b/packages/api/src/apps/routes/putApp.route.js @@ -9,7 +9,7 @@ module.exports = { path: '/apps/{app}', config: { pre: [ - hasScopeInList('apps:modify'), + hasScopeInList(['apps:modify']), hasRoleInList(permissions.editApp), ], validate: { diff --git a/packages/api/src/hooks/routes/deleteHook.route.js b/packages/api/src/hooks/routes/deleteHook.route.js index e7d5943..7cdc715 100644 --- a/packages/api/src/hooks/routes/deleteHook.route.js +++ b/packages/api/src/hooks/routes/deleteHook.route.js @@ -8,7 +8,7 @@ module.exports = { method: 'DELETE', path: '/hooks/{hook}', config: { - pre: [hasScopeInList('hooks:delete'), hasRoleInList(permissions.deleteHook)], + pre: [hasScopeInList(['hooks:delete']), hasRoleInList(permissions.deleteHook)], validate: { params, }, diff --git a/packages/api/src/hooks/routes/getHook.route.js b/packages/api/src/hooks/routes/getHook.route.js index 65bc7ca..adbcb83 100644 --- a/packages/api/src/hooks/routes/getHook.route.js +++ b/packages/api/src/hooks/routes/getHook.route.js @@ -7,7 +7,7 @@ module.exports = { method: 'GET', path: '/hooks/{hook}', config: { - pre: [hasScopeInList('hooks:get')], + pre: [hasScopeInList(['hooks:get'])], validate: { params, }, diff --git a/packages/api/src/hooks/routes/getHooks.route.js b/packages/api/src/hooks/routes/getHooks.route.js index 45218ca..b5dde6d 100644 --- a/packages/api/src/hooks/routes/getHooks.route.js +++ b/packages/api/src/hooks/routes/getHooks.route.js @@ -5,7 +5,7 @@ module.exports = { method: 'GET', path: '/hooks', config: { - pre: [hasScopeInList('hooks:get')], + pre: [hasScopeInList(['hooks:get'])], validate: { query: Joi.object().keys({ appId: Joi.string().required(), diff --git a/packages/api/src/hooks/routes/postHook.route.js b/packages/api/src/hooks/routes/postHook.route.js index 928971b..d95d28a 100644 --- a/packages/api/src/hooks/routes/postHook.route.js +++ b/packages/api/src/hooks/routes/postHook.route.js @@ -8,7 +8,7 @@ module.exports = { path: '/hooks', method: 'POST', config: { - pre: [hasScopeInList('hooks:create'), hasRoleInList(permissions.addHook)], + pre: [hasScopeInList(['hooks:create']), hasRoleInList(permissions.addHook)], validate: { payload: { ...payload, appId: Joi.string().required() }, }, diff --git a/packages/api/src/hooks/routes/putHook.route.js b/packages/api/src/hooks/routes/putHook.route.js index 9b98f10..7ec4808 100644 --- a/packages/api/src/hooks/routes/putHook.route.js +++ b/packages/api/src/hooks/routes/putHook.route.js @@ -9,7 +9,7 @@ module.exports = { path: '/hooks/{hook}', config: { pre: [ - hasScopeInList('hooks:modify'), + hasScopeInList(['hooks:modify']), hasRoleInList(permissions.editHook), ], validate: { diff --git a/packages/api/src/middlewares.js b/packages/api/src/middlewares.js index 19c134f..0d16b49 100644 --- a/packages/api/src/middlewares.js +++ b/packages/api/src/middlewares.js @@ -31,7 +31,7 @@ const isConnectedUser = { failAction: 'ignore', }; -function hasScopeInList(...wantedScopes) { +function hasScopeInList(wantedScopes) { return { method(request) { const { scopes } = request.auth.credentials; diff --git a/packages/api/src/users/models/user.model.js b/packages/api/src/users/models/user.model.js index aeb6fca..66947fe 100644 --- a/packages/api/src/users/models/user.model.js +++ b/packages/api/src/users/models/user.model.js @@ -14,7 +14,7 @@ const userSchema = new mongoose.Schema({ tags: [String], phone: { type: String, set: formatPhoneNumber }, job: String, - password: String, + password: { type: String, select: false }, roles: [String], githubHandle: String, trelloHandle: String, @@ -57,7 +57,7 @@ userSchema.methods.comparePassword = function comparePassword(password) { }; userSchema.statics.findOneByEmailAndPassword = function findOneByEmailAndPassword(email, password) { - return this.findOne({ email }) + return this.findOne({ email }).select('+password') .then((user) => { if (user === null) throw Error('user_not_found'); return user.comparePassword(password) diff --git a/packages/api/src/users/routes/cget-users.js b/packages/api/src/users/routes/cget-users.js index 7a18926..a398b6b 100644 --- a/packages/api/src/users/routes/cget-users.js +++ b/packages/api/src/users/routes/cget-users.js @@ -5,7 +5,7 @@ module.exports = { method: 'GET', path: '/users', config: { - pre: [hasScopeInList('users:get')], + pre: [hasScopeInList(['users:get'])], validate: { query: Joi.object().keys({ email: Joi.string().max(50), diff --git a/packages/api/src/users/routes/delete-users.js b/packages/api/src/users/routes/delete-users.js index df0050a..3f946ea 100644 --- a/packages/api/src/users/routes/delete-users.js +++ b/packages/api/src/users/routes/delete-users.js @@ -9,24 +9,25 @@ module.exports = { method: 'DELETE', path: '/users/{user}', config: { - pre: [hasScopeInList('users:delete'), hasRoleInList(permissions.deleteUser)], + pre: [hasScopeInList(['users:delete']), hasRoleInList(permissions.deleteUser)], validate: { params, }, }, async handler(req) { const { User } = req.server.plugins.users.models; - const { n: deleted } = await User.remove({ _id: req.params.user }); - if (!deleted) { + const user = await User.findById(req.params.user); + if (!user) { throw Boom.notFound(); } + await User.remove({ _id: req.params.user }); await req.server.methods.cleanupUserAuth(req.params.user); req.server.plugins.hooks.trigger(hooks.events.userDeleted, { - userId: req.params.user, - sender: _.omit(req.auth.credentials.user.toJSON(), ['password', 'thirdParty', 'needPasswordChange']), + user: _.omit(user.toJSON(), ['thirdParty', 'needPasswordChange']), + sender: _.omit(req.auth.credentials.user.toJSON(), ['thirdParty', 'needPasswordChange']), }); return { deleted: true }; diff --git a/packages/api/src/users/routes/get-me.js b/packages/api/src/users/routes/get-me.js index 02d40a7..67de372 100644 --- a/packages/api/src/users/routes/get-me.js +++ b/packages/api/src/users/routes/get-me.js @@ -4,7 +4,7 @@ module.exports = { method: 'GET', path: '/users/me', config: { - pre: [hasScopeInList('profile:get')], + pre: [hasScopeInList(['profile:get'])], }, handler(req, res) { return res.mongodb(req.auth.credentials.user, ['password', 'thirdParty', 'needPasswordChange']); diff --git a/packages/api/src/users/routes/get-users.js b/packages/api/src/users/routes/get-users.js index fe8ce90..54d0333 100644 --- a/packages/api/src/users/routes/get-users.js +++ b/packages/api/src/users/routes/get-users.js @@ -6,7 +6,7 @@ module.exports = { method: 'GET', path: '/users/{user}', config: { - pre: [hasScopeInList('users:get', 'profile:get')], + pre: [hasScopeInList(['users:get', 'profile:get'])], validate: { params, }, diff --git a/packages/api/src/users/routes/post-users.js b/packages/api/src/users/routes/post-users.js index 46029f6..91a8f0b 100644 --- a/packages/api/src/users/routes/post-users.js +++ b/packages/api/src/users/routes/post-users.js @@ -9,7 +9,7 @@ module.exports = { method: 'POST', path: '/users', config: { - pre: [hasScopeInList('users:create'), hasRoleInList(permissions.addUser)], + pre: [hasScopeInList(['users:create']), hasRoleInList(permissions.addUser)], validate: { payload: payload.post, }, diff --git a/packages/api/src/users/routes/put-users.js b/packages/api/src/users/routes/put-users.js index 0897227..a764f68 100644 --- a/packages/api/src/users/routes/put-users.js +++ b/packages/api/src/users/routes/put-users.js @@ -4,14 +4,13 @@ const { permissions, hooks } = require('@lvconnect/config/server'); const { hasRoleInList, isConnectedUser, hasScopeInList } = require('../../middlewares'); const { payload, params } = require('./user-validation'); -const filter = require('lodash/pickBy'); module.exports = { method: 'PUT', path: '/users/{user}', config: { pre: [ - hasScopeInList('users:modify', 'profile:modify'), + hasScopeInList(['users:modify', 'profile:modify']), isConnectedUser, hasRoleInList(permissions.editUser, true), ], @@ -23,8 +22,8 @@ module.exports = { async handler(req, res) { const { User } = req.server.plugins.users.models; const { isConnectedUser: isSelf, hasRights, scopes } = req.pre; - const hasEditAnyUserScope = scopes.indexOf('users:modify') !== -1; - const hasEditSelfScope = scopes.indexOf('profile:modify') !== -1; + const hasEditAnyUserScope = scopes.indexOf('users:modify') >= 0; + const hasEditSelfScope = scopes.indexOf('profile:modify') >= 0; const { githubOrgUserLink, trelloOrgUserLink } = req.server.plugins.tasks; // Check can edit other users @@ -42,30 +41,35 @@ module.exports = { throw Boom.forbidden('insufficient_rights'); } - const updates = filter({ - $set: filter(req.payload, value => value !== null), - $unset: filter(req.payload, value => value === null), - }, update => Object.keys(update).length); + const user = await User.findById(req.params.user); - const savedUser = await User - .findOneAndUpdate({ _id: req.params.user }, updates, { new: true, runSettersOnQuery: true }); - - if (!savedUser) { + if (!user) { throw Boom.notFound('User Not Found'); } - if (savedUser.githubHandle && savedUser.thirdParty.github !== 'success') { - githubOrgUserLink({ user: savedUser }); + const oldUser = user.toJSON(); + Object.assign(user, req.payload); + Object.entries(req.payload).forEach(([key, value]) => { + if (value === null) { + user[key] = undefined; + } + }); + + await user.save(); + + if (user.githubHandle && user.thirdParty.github !== 'success') { + githubOrgUserLink({ user }); } - if (savedUser.trelloHandle && savedUser.thirdParty.trello !== 'success') { - trelloOrgUserLink({ user: savedUser }); + if (user.trelloHandle && user.thirdParty.trello !== 'success') { + trelloOrgUserLink({ user }); } req.server.plugins.hooks.trigger(hooks.events.userModified, { - user: _.omit(savedUser.toJSON(), ['password', 'thirdParty', 'needPasswordChange']), - sender: _.omit(req.auth.credentials.user.toJSON(), ['password', 'thirdParty', 'needPasswordChange']), + oldUser: _.omit(oldUser, ['thirdParty', 'needPasswordChange']), + user: _.omit(user.toJSON(), ['thirdParty', 'needPasswordChange']), + sender: _.omit(req.auth.credentials.user.toJSON(), ['thirdParty', 'needPasswordChange']), }); - return res.mongodb(savedUser, ['password', 'thirdParty', 'needPasswordChange']); + return res.mongodb(user, ['thirdParty', 'needPasswordChange']); }, }; diff --git a/packages/api/src/users/routes/user-validation.js b/packages/api/src/users/routes/user-validation.js index e4c0489..46c143b 100644 --- a/packages/api/src/users/routes/user-validation.js +++ b/packages/api/src/users/routes/user-validation.js @@ -33,19 +33,19 @@ const commonFields = { lastName: Joi.string().min(2).required(), roles: Joi.array().items(Joi.string().valid(validRoles)).min(1).required(), city: Joi.string().valid(cities).required(), - description: Joi.string().max(255).empty(''), - phone: customJoi.string().phone(), - job: Joi.string(), + description: Joi.string().max(255).empty('').allow(null), + phone: customJoi.string().phone().allow(null), + job: Joi.string().allow(null), tags: Joi.array().items(Joi.string()), - hiredAt: Joi.date().iso(), - leftAt: Joi.date().iso(), - birthDate: Joi.date().iso(), - registrationNumber: Joi.string(), + hiredAt: Joi.date().iso().allow(null), + leftAt: Joi.date().iso().allow(null), + birthDate: Joi.date().iso().allow(null), + registrationNumber: Joi.string().allow(null), address: Joi.object().keys({ street: Joi.string(), zipCode: Joi.string(), city: Joi.string(), - }), + }).allow(null), }; exports.payload = { diff --git a/packages/app/modules/auth/pages/login.page.jsx b/packages/app/modules/auth/pages/login.page.jsx index 9cc0fb8..5f7bd4e 100644 --- a/packages/app/modules/auth/pages/login.page.jsx +++ b/packages/app/modules/auth/pages/login.page.jsx @@ -24,7 +24,8 @@ const styles = theme => ({ alignItems: 'center', justifyContent: 'center', flexDirection: 'column', - height: `calc(100% + ${theme.spacing.unit * 6}px)`, + marginBottom: -theme.spacing.unit * 5, + height: `calc(100vh - ${theme.spacing.unit * 8}px)`, boxSizing: 'border-box', background: `url(${bgUrl}) no-repeat`, backgroundSize: 'cover',