diff --git a/app/api/server/v1/roles.js b/app/api/server/v1/roles.js index 22a0d543ce34..7772f80e29d7 100644 --- a/app/api/server/v1/roles.js +++ b/app/api/server/v1/roles.js @@ -13,6 +13,23 @@ API.v1.addRoute('roles.list', { authRequired: true }, { }, }); +API.v1.addRoute('roles.sync', { authRequired: true }, { + get() { + const { updatedSince } = this.queryParams; + + if (isNaN(Date.parse(updatedSince))) { + throw new Meteor.Error('error-updatedSince-param-invalid', 'The "updatedSince" query parameter must be a valid date.'); + } + + return API.v1.success({ + roles: { + update: Roles.findByUpdatedDate(new Date(updatedSince), { fields: API.v1.defaultFieldsToExclude }).fetch(), + remove: Roles.trashFindDeletedAfter(new Date(updatedSince)).fetch(), + }, + }); + }, +}); + API.v1.addRoute('roles.create', { authRequired: true }, { post() { check(this.bodyParams, { diff --git a/app/models/server/models/Roles.js b/app/models/server/models/Roles.js index a2e9fa3418f6..2715ab05d7c1 100644 --- a/app/models/server/models/Roles.js +++ b/app/models/server/models/Roles.js @@ -85,6 +85,14 @@ export class Roles extends Base { return this.findOne(query, options); } + findByUpdatedDate(updatedAfterDate, options) { + const query = { + _updatedAt: { $gte: new Date(updatedAfterDate) }, + }; + + return this.find(query, options); + } + canAddUserToRole(uid, roleName, scope) { const role = this.findOne({ _id: roleName }, { fields: { scope: 1 } }); if (!role) { diff --git a/tests/end-to-end/api/13-roles.js b/tests/end-to-end/api/13-roles.js index 26b867ee154a..b3a3b1611375 100644 --- a/tests/end-to-end/api/13-roles.js +++ b/tests/end-to-end/api/13-roles.js @@ -35,6 +35,33 @@ describe('[Roles]', function() { }); }); + describe('GET [/roles.sync]', () => { + it('should return an array of roles which are updated after updatedSice date when search by "updatedSince" query parameter', (done) => { + request.get(api('roles.sync?updatedSince=2018-11-27T13:52:01Z')) + .set(credentials) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('roles'); + expect(res.body.roles).to.have.property('update').and.to.be.an('array'); + expect(res.body.roles).to.have.property('remove').and.to.be.an('array'); + }) + .end(done); + }); + + it('should return an error when updatedSince query parameter is not a valid ISODate string', (done) => { + request.get(api('roles.sync?updatedSince=fsafdf')) + .set(credentials) + .expect('Content-Type', 'application/json') + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('success', false); + }) + .end(done); + }); + }); + describe('POST [/roles.create]', () => { it('should create a new role with Users scope', (done) => { request.post(api('roles.create'))