From 8fd4b3f09f8b59f6d562050a31bb400070976c24 Mon Sep 17 00:00:00 2001 From: Rishabh Garg Date: Wed, 30 Jan 2019 17:06:09 +0530 Subject: [PATCH] Added new admin API for members (#10435) no issue - Added read and browse admin API for members --- core/server/api/v2/index.js | 4 +++ core/server/api/v2/members.js | 35 +++++++++++++++++++ .../api/v2/utils/serializers/output/index.js | 4 +++ .../v2/utils/serializers/output/members.js | 24 +++++++++++++ core/server/lib/members/index.js | 2 ++ core/server/lib/members/users.js | 6 ++-- core/server/services/members/api.js | 22 +++++++++--- core/server/translations/en.json | 4 +++ core/server/web/api/v2/admin/routes.js | 4 +++ core/server/web/shared/middlewares/labs.js | 7 ++++ 10 files changed, 105 insertions(+), 7 deletions(-) create mode 100644 core/server/api/v2/members.js create mode 100644 core/server/api/v2/utils/serializers/output/members.js diff --git a/core/server/api/v2/index.js b/core/server/api/v2/index.js index 5ae2e46de2..932dd9ce2c 100644 --- a/core/server/api/v2/index.js +++ b/core/server/api/v2/index.js @@ -63,6 +63,10 @@ module.exports = { return shared.pipeline(require('./subscribers'), localUtils); }, + get members() { + return shared.pipeline(require('./members'), localUtils); + }, + get upload() { return shared.pipeline(require('./upload'), localUtils); }, diff --git a/core/server/api/v2/members.js b/core/server/api/v2/members.js new file mode 100644 index 0000000000..5b8dfb997b --- /dev/null +++ b/core/server/api/v2/members.js @@ -0,0 +1,35 @@ +const memberUserObject = require('../../services/members').api.memberUserObject; + +const members = { + docName: 'members', + browse: { + options: [ + 'limit', + 'fields', + 'filter', + 'order', + 'debug', + 'page' + ], + permissions: true, + validation: {}, + query(frame) { + return memberUserObject.list(frame.options); + } + }, + + read: { + headers: {}, + data: [ + 'id', + 'email' + ], + validation: {}, + permissions: true, + query(frame) { + return memberUserObject.get(frame.data, frame.options); + } + } +}; + +module.exports = members; diff --git a/core/server/api/v2/utils/serializers/output/index.js b/core/server/api/v2/utils/serializers/output/index.js index dbdb67d02e..89d584b28e 100644 --- a/core/server/api/v2/utils/serializers/output/index.js +++ b/core/server/api/v2/utils/serializers/output/index.js @@ -55,6 +55,10 @@ module.exports = { return require('./subscribers'); }, + get members() { + return require('./members'); + }, + get upload() { return require('./upload'); }, diff --git a/core/server/api/v2/utils/serializers/output/members.js b/core/server/api/v2/utils/serializers/output/members.js new file mode 100644 index 0000000000..aadf1391d5 --- /dev/null +++ b/core/server/api/v2/utils/serializers/output/members.js @@ -0,0 +1,24 @@ +const common = require('../../../../../lib/common'); +const debug = require('ghost-ignition').debug('api:v2:utils:serializers:output:members'); + +module.exports = { + browse(data, apiConfig, frame) { + debug('browse'); + + frame.response = data; + }, + + read(data, apiConfig, frame) { + debug('read'); + + if (!data) { + return Promise.reject(new common.errors.NotFoundError({ + message: common.i18n.t('errors.api.members.memberNotFound') + })); + } + + frame.response = { + members: [data] + }; + } +}; diff --git a/core/server/lib/members/index.js b/core/server/lib/members/index.js index 7769077ceb..1f9cf6deeb 100644 --- a/core/server/lib/members/index.js +++ b/core/server/lib/members/index.js @@ -20,6 +20,7 @@ module.exports = function MembersApi({ validateMember, updateMember, getMember, + listMembers, sendEmail }) { const {encodeToken, decodeToken, getPublicKeys} = Tokens({privateKey, publicKey, issuer}); @@ -31,6 +32,7 @@ module.exports = function MembersApi({ validateMember, sendEmail, encodeToken, + listMembers, decodeToken }); diff --git a/core/server/lib/members/users.js b/core/server/lib/members/users.js index a436ed804d..37decca252 100644 --- a/core/server/lib/members/users.js +++ b/core/server/lib/members/users.js @@ -2,13 +2,14 @@ module.exports = function ({ createMember, updateMember, getMember, + listMembers, validateMember, sendEmail, encodeToken, decodeToken }) { function requestPasswordReset({email}) { - return getMember({email}).then((member) => { + return getMember({email}, {require: true}).then((member) => { return encodeToken({ sub: member.id }).then((token) => { @@ -30,6 +31,7 @@ module.exports = function ({ resetPassword, create: createMember, validate: validateMember, - get: getMember + get: getMember, + list: listMembers }; }; diff --git a/core/server/services/members/api.js b/core/server/services/members/api.js index 4a4391e111..738757e7ff 100644 --- a/core/server/services/members/api.js +++ b/core/server/services/members/api.js @@ -25,11 +25,22 @@ function updateMember(member, newData) { }); } -function getMember(member) { - return models.Member.findOne(member, { - require: true - }).then((member) => { - return member.toJSON(); +function getMember(data, options) { + options = options || {}; + return models.Member.findOne(data, options).then((model) => { + if (!model) { + return null; + } + return model.toJSON(options); + }); +} + +function listMembers(options) { + return models.Member.findPage(options).then((models) => { + return { + members: models.data.map(model => model.toJSON(options)), + meta: models.meta + }; }); } @@ -104,6 +115,7 @@ const api = MembersApi({ validateAudience, createMember, getMember, + listMembers, validateMember, updateMember, sendEmail diff --git a/core/server/translations/en.json b/core/server/translations/en.json index b71cf279bc..83dcc9e1f9 100644 --- a/core/server/translations/en.json +++ b/core/server/translations/en.json @@ -403,6 +403,10 @@ "subscriberNotFound": "Subscriber not found.", "subscriberAlreadyExists": "Email address is already subscribed." }, + "members": { + "memberNotFound": "Member not found.", + "memberAlreadyExists": "Email address is already member." + }, "tags": { "tagNotFound": "Tag not found." }, diff --git a/core/server/web/api/v2/admin/routes.js b/core/server/web/api/v2/admin/routes.js index 4645ca4eb9..eb5f872558 100644 --- a/core/server/web/api/v2/admin/routes.js +++ b/core/server/web/api/v2/admin/routes.js @@ -94,6 +94,10 @@ module.exports = function apiRoutes() { router.del('/subscribers/:id', shared.middlewares.labs.subscribers, mw.authAdminApi, apiv2.http(apiv2.subscribers.destroy)); router.del('/subscribers/email/:email', shared.middlewares.labs.subscribers, mw.authAdminApi, apiv2.http(apiv2.subscribers.destroy)); + // ## Members + router.get('/members', shared.middlewares.labs.members, mw.authAdminApi, apiv2.http(apiv2.members.browse)); + router.get('/members/:id', shared.middlewares.labs.members, mw.authAdminApi, apiv2.http(apiv2.members.read)); + // ## Roles router.get('/roles/', mw.authAdminApi, apiv2.http(apiv2.roles.browse)); diff --git a/core/server/web/shared/middlewares/labs.js b/core/server/web/shared/middlewares/labs.js index b73bc7aa25..d0efb7932b 100644 --- a/core/server/web/shared/middlewares/labs.js +++ b/core/server/web/shared/middlewares/labs.js @@ -8,6 +8,13 @@ const labs = { } else { return next(new common.errors.NotFoundError()); } + }, + members(req, res, next) { + if (labsUtil.isSet('members') === true) { + return next(); + } else { + return next(new common.errors.NotFoundError()); + } } };