diff --git a/.changeset/hungry-fans-wait.md b/.changeset/hungry-fans-wait.md new file mode 100644 index 00000000000..7d8594f3470 --- /dev/null +++ b/.changeset/hungry-fans-wait.md @@ -0,0 +1,5 @@ +--- +'@rocket.chat/meteor': minor +--- + +Validates attachment fields to require `title` and `value` properties on APIs `chat.postMessage` and `chat.sendMessage`. diff --git a/apps/meteor/app/lib/server/functions/sendMessage.ts b/apps/meteor/app/lib/server/functions/sendMessage.ts index d5608e4abde..6af459f2332 100644 --- a/apps/meteor/app/lib/server/functions/sendMessage.ts +++ b/apps/meteor/app/lib/server/functions/sendMessage.ts @@ -79,8 +79,8 @@ const validateAttachmentsFields = (attachmentField: any) => { }), ); - if (typeof attachmentField.value !== 'undefined') { - attachmentField.value = String(attachmentField.value); + if (!attachmentField.value || !attachmentField.title) { + throw new Error('Invalid attachment field, title and value is required'); } }; diff --git a/apps/meteor/tests/end-to-end/api/chat.ts b/apps/meteor/tests/end-to-end/api/chat.ts index 382df1f8cbf..87242f88b05 100644 --- a/apps/meteor/tests/end-to-end/api/chat.ts +++ b/apps/meteor/tests/end-to-end/api/chat.ts @@ -464,6 +464,126 @@ describe('[Chat]', () => { .end(done); }); + it('should throw an error when the properties (attachments.fields.title) is missing', (done) => { + void request + .post(api('chat.postMessage')) + .set(credentials) + .send({ + channel: testChannel.name, + text: 'Sample message', + emoji: ':smirk:', + alias: 'Gruggy', + avatar: 'http://res.guggy.com/logo_128.png', + attachments: [ + { + color: '#ff0000', + text: 'Yay for gruggy!', + ts: '2016-12-09T16:53:06.761Z', + thumb_url: 'http://res.guggy.com/logo_128.png', + message_link: 'https://google.com', + collapsed: false, + author_name: 'Bradley Hilton', + author_link: 'https://rocket.chat/', + author_icon: 'https://avatars.githubusercontent.com/u/850391?v=3', + title: 'Attachment Example', + title_link: 'https://youtube.com', + title_link_download: true, + image_url: 'http://res.guggy.com/logo_128.png', + audio_url: 'http://www.w3schools.com/tags/horse.mp3', + video_url: 'http://www.w3schools.com/tags/movie.mp4', + fields: [ + { + short: true, + value: 'This is attachment field value', + }, + ], + }, + ], + }) + .expect('Content-Type', 'application/json') + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('error'); + }) + .end(done); + }); + + it('should throw an error when the properties (attachments.fields.value) is missing', (done) => { + void request + .post(api('chat.postMessage')) + .set(credentials) + .send({ + channel: testChannel.name, + text: 'Sample message', + emoji: ':smirk:', + alias: 'Gruggy', + avatar: 'http://res.guggy.com/logo_128.png', + attachments: [ + { + color: '#ff0000', + text: 'Yay for gruggy!', + ts: '2016-12-09T16:53:06.761Z', + thumb_url: 'http://res.guggy.com/logo_128.png', + message_link: 'https://google.com', + collapsed: false, + author_name: 'Bradley Hilton', + author_link: 'https://rocket.chat/', + author_icon: 'https://avatars.githubusercontent.com/u/850391?v=3', + title: 'Attachment Example', + title_link: 'https://youtube.com', + title_link_download: true, + image_url: 'http://res.guggy.com/logo_128.png', + audio_url: 'http://www.w3schools.com/tags/horse.mp3', + video_url: 'http://www.w3schools.com/tags/movie.mp4', + fields: [ + { + short: true, + title: 'This is attachment field title', + }, + ], + }, + ], + }) + .expect('Content-Type', 'application/json') + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('success', false); + expect(res.body).to.have.property('error'); + }) + .end(done); + }); + + it('attachment.fields should work fine when value and title are provided', (done) => { + void request + .post(api('chat.postMessage')) + .set(credentials) + .send({ + channel: testChannel.name, + text: 'Sample message', + attachments: [ + { + text: 'This is attachment field', + color: '#764FA5', + fields: [{ short: true, value: 'This is value', title: 'This is title' }], + }, + ], + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.not.have.property('error'); + expect(res.body).to.have.nested.property('message.msg', 'Sample message'); + expect(res.body).to.have.nested.property('message.attachments').to.be.an('array'); + expect(res.body).to.have.nested.property('message.attachments[0].fields').to.be.an('array'); + expect(res.body).to.have.nested.property('message.attachments[0].fields[0].short', true); + expect(res.body).to.have.nested.property('message.attachments[0].fields[0].value', 'This is value'); + expect(res.body).to.have.nested.property('message.attachments[0].fields[0].title', 'This is title'); + }) + .end(done); + }); + it('should return statusCode 200 when postMessage successfully', (done) => { void request .post(api('chat.postMessage'))