diff --git a/app/api/server/v1/integrations.js b/app/api/server/v1/integrations.js index 8c71129a41e1e..480c3e8743eb1 100644 --- a/app/api/server/v1/integrations.js +++ b/app/api/server/v1/integrations.js @@ -190,3 +190,61 @@ API.v1.addRoute('integrations.get', { authRequired: true }, { }); }, }); + +API.v1.addRoute('integrations.update', { authRequired: true }, { + put() { + check(this.bodyParams, Match.ObjectIncluding({ + type: String, + name: String, + enabled: Boolean, + username: String, + urls: Match.Maybe([String]), + channel: String, + event: Match.Maybe(String), + triggerWords: Match.Maybe([String]), + alias: Match.Maybe(String), + avatar: Match.Maybe(String), + emoji: Match.Maybe(String), + token: Match.Maybe(String), + scriptEnabled: Boolean, + script: Match.Maybe(String), + targetChannel: Match.Maybe(String), + integrationId: Match.Maybe(String), + target_url: Match.Maybe(String), + })); + + let integration; + switch (this.bodyParams.type) { + case 'webhook-outgoing': + if (this.bodyParams.target_url) { + integration = Integrations.findOne({ urls: this.bodyParams.target_url }); + } else if (this.bodyParams.integrationId) { + integration = Integrations.findOne({ _id: this.bodyParams.integrationId }); + } + + if (!integration) { + return API.v1.failure('No integration found.'); + } + + Meteor.call('updateOutgoingIntegration', integration._id, this.bodyParams); + + return API.v1.success({ + integration: Integrations.findOne({ _id: integration._id }), + }); + case 'webhook-incoming': + integration = Integrations.findOne({ _id: this.bodyParams.integrationId }); + + if (!integration) { + return API.v1.failure('No integration found.'); + } + + Meteor.call('updateIncomingIntegration', integration._id, this.bodyParams); + + return API.v1.success({ + integration: Integrations.findOne({ _id: integration._id }), + }); + default: + return API.v1.failure('Invalid integration type.'); + } + }, +}); diff --git a/tests/end-to-end/api/07-incoming-integrations.js b/tests/end-to-end/api/07-incoming-integrations.js index efbcf7e87e1ed..eaf7153be8259 100644 --- a/tests/end-to-end/api/07-incoming-integrations.js +++ b/tests/end-to-end/api/07-incoming-integrations.js @@ -348,6 +348,48 @@ describe('[Incoming Integrations]', function() { }); }); + describe('[/integrations.update]', () => { + it('should update an integration by id and return the new data', (done) => { + request.put(api('integrations.update')) + .set(credentials) + .send({ + type: 'webhook-incoming', + name: 'Incoming test updated', + enabled: true, + alias: 'test updated', + username: 'rocket.cat', + scriptEnabled: true, + channel: '#general', + integrationId: integration._id, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('integration'); + expect(res.body.integration._id).to.be.equal(integration._id); + expect(res.body.integration.name).to.be.equal('Incoming test updated'); + expect(res.body.integration.alias).to.be.equal('test updated'); + }) + .end(done); + }); + + it('should have integration updated on subsequent gets', (done) => { + request.get(api(`integrations.get?integrationId=${ integration._id }`)) + .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('integration'); + expect(res.body.integration._id).to.be.equal(integration._id); + expect(res.body.integration.name).to.be.equal('Incoming test updated'); + expect(res.body.integration.alias).to.be.equal('test updated'); + }) + .end(done); + }); + }); + describe('[/integrations.remove]', () => { it('should return an error when the user DOES NOT have the permission "manage-incoming-integrations" to remove an incoming integration', (done) => { updatePermission('manage-incoming-integrations', []).then(() => {