diff --git a/ghost/members-api/lib/repositories/MemberRepository.js b/ghost/members-api/lib/repositories/MemberRepository.js index 3019f331e5..0065f36658 100644 --- a/ghost/members-api/lib/repositories/MemberRepository.js +++ b/ghost/members-api/lib/repositories/MemberRepository.js @@ -19,7 +19,7 @@ const messages = { bulkActionRequiresFilter: 'Cannot perform {action} without a filter or all=true', tierArchived: 'Cannot use archived Tiers', invalidEmail: 'Invalid Email', - invalidNewsletterId: 'Cannot subscribe to invalid newsletter {id}' + invalidNewsletterId: 'Cannot subscribe to invalid newsletter {ids}' }; /** @@ -284,13 +284,19 @@ module.exports = class MemberRepository { //checks for custom signUp forms if (memberData.newsletters && memberData.newsletters.length > 0) { - const savedNewsletter = await this._newslettersService.browse({filter: `id:'${memberData.newsletters[0].id}'`}); - if (savedNewsletter.length === 0) { - throw new errors.BadRequestError({message: tpl(messages.invalidNewsletterId, {id: memberData.newsletters[0].id})}); - } - if (savedNewsletter[0].status === 'archived') { - memberData.newsletters = []; + const newsletterIds = memberData.newsletters.map(newsletter => newsletter.id); + const newsletters = await this._newslettersService.browse({ + filter: `id:[${newsletterIds}]`, + columns: ['id','status'] + }); + if (newsletters.length !== newsletterIds.length) { + const validNewsletterIds = newsletters.map(newsletter => newsletter.id); + const invalidIds = newsletterIds.filter(id => !validNewsletterIds.includes(id)); + throw new errors.BadRequestError({message: tpl(messages.invalidNewsletterId, {ids: invalidIds})}); } + memberData.newsletters = newsletters + .filter(newsletter => newsletter.status === 'active') + .map(newsletter => ({id: newsletter.id})); } // Subscribe members to default newsletters diff --git a/ghost/members-api/test/unit/lib/repositories/member.test.js b/ghost/members-api/test/unit/lib/repositories/member.test.js index 35b639013b..37d4e0a4ca 100644 --- a/ghost/members-api/test/unit/lib/repositories/member.test.js +++ b/ghost/members-api/test/unit/lib/repositories/member.test.js @@ -337,17 +337,27 @@ describe('MemberRepository', function () { }; }); - it('subscribes a member to a specified newsletter', async function () { - const newsletter = { + it('subscribes a member to the specified newsletters', async function () { + const newsletters = [{ id: 'abc123', status: 'active' - }; + }, + { + id: 'def456', + status: 'active' + }, + { + id: 'ghi789', + status: 'active' + }]; + const newsletterIds = newsletters.map(newsletter => newsletter.id); newslettersServiceStub.browse .withArgs({ - filter: `id:'${newsletter.id}'` + filter: `id:[${newsletterIds}]`, + columns: ['id', 'status'] }) - .resolves([newsletter]); + .resolves(newsletters); const repo = new MemberRepository({ Member: memberModelStub, @@ -364,14 +374,18 @@ describe('MemberRepository', function () { email: 'jamie@example.com', email_disabled: false, newsletters: [ - {id: newsletter.id} + {id: newsletters[0].id}, + {id: newsletters[1].id}, + {id: newsletters[2].id} ] }); newslettersServiceStub.browse.calledOnce.should.be.true(); memberModelStub.add.calledOnce.should.be.true(); memberModelStub.add.args[0][0].newsletters.should.eql([ - {id: newsletter.id} + {id: newsletters[0].id}, + {id: newsletters[1].id}, + {id: newsletters[2].id} ]); }); @@ -380,7 +394,8 @@ describe('MemberRepository', function () { newslettersServiceStub.browse .withArgs({ - filter: `id:'${INVALID_NEWSLETTER_ID}'` + filter: `id:[${INVALID_NEWSLETTER_ID}]`, + columns: ['id', 'status'] }) .resolves([]); @@ -412,7 +427,8 @@ describe('MemberRepository', function () { newslettersServiceStub.browse .withArgs({ - filter: `id:'${newsletter.id}'` + filter: `id:[${newsletter.id}]`, + columns: ['id', 'status'] }) .resolves([newsletter]);