Added GET/DELETE /subscribers/email/:email/ endpoints (#9238)

no issue

- useful for managing subscribers via external systems/API calls where it's likely only the e-mail address will be known
- adds `GET /subscribers/email/:email/`
- adds `DELETE /subscribers/email/:email/`
This commit is contained in:
Kevin Ansfield 2017-11-14 11:09:41 +00:00 committed by Katharina Irrgang
parent 0d54326121
commit bcc98e5536
4 changed files with 69 additions and 6 deletions

View File

@ -84,9 +84,11 @@ module.exports = function apiRoutes() {
api.http(api.subscribers.importCSV)
);
apiRouter.get('/subscribers/:id', labs.subscribers, mw.authenticatePrivate, api.http(api.subscribers.read));
apiRouter.get('/subscribers/email/:email', labs.subscribers, mw.authenticatePrivate, api.http(api.subscribers.read));
apiRouter.post('/subscribers', labs.subscribers, mw.authenticatePublic, api.http(api.subscribers.add));
apiRouter.put('/subscribers/:id', labs.subscribers, mw.authenticatePrivate, api.http(api.subscribers.edit));
apiRouter.del('/subscribers/:id', labs.subscribers, mw.authenticatePrivate, api.http(api.subscribers.destroy));
apiRouter.del('/subscribers/email/:email', labs.subscribers, mw.authenticatePrivate, api.http(api.subscribers.destroy));
// ## Roles
apiRouter.get('/roles/', mw.authenticatePrivate, api.http(api.roles.browse));

View File

@ -53,7 +53,7 @@ subscribers = {
* @return {Promise<Subscriber>} Subscriber
*/
read: function read(options) {
var attrs = ['id'],
var attrs = ['id', 'email'],
tasks;
/**
@ -190,6 +190,29 @@ subscribers = {
destroy: function destroy(options) {
var tasks;
/**
* ### Delete Subscriber
* If we have an email param, check the subscriber exists
* @type {[type]}
*/
function getSubscriberByEmail(options) {
if (options.email) {
return models.Subscriber.getByEmail(options.email, options)
.then(function (subscriber) {
if (!subscriber) {
return Promise.reject(new errors.NotFoundError({
message: i18n.t('errors.api.subscribers.subscriberNotFound')
}));
}
options.id = subscriber.get('id');
return options;
});
}
return options;
}
/**
* ### Delete Subscriber
* Make the call to the Model layer
@ -201,8 +224,9 @@ subscribers = {
// Push all of our tasks into a `tasks` array in the correct order
tasks = [
apiUtils.validate(docName, {opts: apiUtils.idDefaultOptions}),
apiUtils.validate(docName, {opts: ['id', 'email']}),
apiUtils.handlePermissions(docName, 'destroy'),
getSubscriberByEmail,
doQuery
];

View File

@ -118,7 +118,8 @@ utils = {
to: {isDate: true},
fields: {matches: /^[\w, ]+$/},
order: {matches: /^[a-z0-9_,\. ]+$/i},
name: {}
name: {},
email: {isEmail: true}
},
// these values are sanitised/validated separately
noValidation = ['data', 'context', 'include', 'filter', 'forUpdate', 'transacting', 'formats'],

View File

@ -155,10 +155,10 @@ describe('Subscribers API', function () {
});
describe('Destroy', function () {
var firstSubscriber = testUtils.DataGenerator.Content.subscribers[0].id;
var firstSubscriber = testUtils.DataGenerator.Content.subscribers[0];
it('can destroy subscriber as admin', function (done) {
SubscribersAPI.destroy(_.extend({}, testUtils.context.admin, {id: firstSubscriber}))
SubscribersAPI.destroy(_.extend({}, testUtils.context.admin, {id: firstSubscriber.id}))
.then(function (results) {
should.not.exist(results);
@ -166,8 +166,28 @@ describe('Subscribers API', function () {
}).catch(done);
});
it('can destroy subscriber by email', function (done) {
SubscribersAPI.destroy(_.extend({}, testUtils.context.admin, {email: firstSubscriber.email}))
.then(function (results) {
should.not.exist(results);
done();
}).catch(done);
});
it('returns NotFoundError for unknown email', function (done) {
SubscribersAPI.destroy(_.extend({}, testUtils.context.admin, {email: 'unknown@example.com'}))
.then(function (results) {
done(new Error('Destroy subscriber should not be possible with unknown email.'));
}, function (err) {
should.exist(err);
(err instanceof errors.NotFoundError).should.eql(true);
done();
}).catch(done);
});
it('CANNOT destroy subscriber', function (done) {
SubscribersAPI.destroy(_.extend({}, testUtils.context.editor, {id: firstSubscriber}))
SubscribersAPI.destroy(_.extend({}, testUtils.context.editor, {id: firstSubscriber.id}))
.then(function () {
done(new Error('Destroy subscriber should not be possible as editor.'));
}, function (err) {
@ -227,6 +247,22 @@ describe('Subscribers API', function () {
}).catch(done);
});
it('with email', function (done) {
SubscribersAPI.browse({context: {user: 1}}).then(function (results) {
should.exist(results);
should.exist(results.subscribers);
results.subscribers.length.should.be.above(0);
var firstSubscriber = _.find(results.subscribers, {id: testUtils.DataGenerator.Content.subscribers[0].id});
return SubscribersAPI.read({context: {user: 1}, email: firstSubscriber.email});
}).then(function (found) {
should.exist(found);
testUtils.API.checkResponse(found.subscribers[0], 'subscriber');
done();
}).catch(done);
});
it('CANNOT fetch a subscriber which doesn\'t exist', function (done) {
SubscribersAPI.read({context: {user: 1}, id: 999}).then(function () {
done(new Error('Should not return a result'));