fix: incoming webhook "Post As" field not updating userId (#35795)

pull/35698/head^2
Abhinav Kumar 9 months ago committed by GitHub
parent ae18eef09b
commit dc6cf3ef5f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 5
      .changeset/angry-poems-build.md
  2. 26
      apps/meteor/app/integrations/server/methods/incoming/updateIncomingIntegration.ts
  3. 1
      apps/meteor/app/integrations/server/methods/outgoing/updateOutgoingIntegration.ts
  4. 66
      apps/meteor/tests/end-to-end/api/incoming-integrations.ts

@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': patch
---
Fixes incorrect message sender for incoming webhooks when "Post As" field is updated by ensuring both username and userId are synced to reflect the selected user.

@ -23,18 +23,14 @@ declare module '@rocket.chat/ddp-client' {
}
}
export const updateIncomingIntegration = async (
userId: string,
integrationId: string,
integration: INewIncomingIntegration | IUpdateIncomingIntegration,
): Promise<IIntegration | null> => {
if (!integration.channel || typeof integration.channel.valueOf() !== 'string' || integration.channel.trim() === '') {
function validateChannels(channelString: string | undefined): string[] {
if (!channelString || typeof channelString.valueOf() !== 'string' || channelString.trim() === '') {
throw new Meteor.Error('error-invalid-channel', 'Invalid channel', {
method: 'updateIncomingIntegration',
});
}
const channels = integration.channel.split(',').map((channel) => channel.trim());
const channels = channelString.split(',').map((channel) => channel.trim());
for (const channel of channels) {
if (!validChannelChars.includes(channel[0])) {
@ -44,6 +40,16 @@ export const updateIncomingIntegration = async (
}
}
return channels;
}
export const updateIncomingIntegration = async (
userId: string,
integrationId: string,
integration: INewIncomingIntegration | IUpdateIncomingIntegration,
): Promise<IIntegration | null> => {
const channels = validateChannels(integration.channel);
let currentIntegration;
if (await hasPermissionAsync(userId, 'manage-incoming-integrations')) {
@ -153,7 +159,8 @@ export const updateIncomingIntegration = async (
}
}
const user = await Users.findOne({ username: currentIntegration.username });
const username = 'username' in integration ? integration.username : currentIntegration.username;
const user = await Users.findOne({ username });
if (!user?._id) {
throw new Meteor.Error('error-invalid-post-as-user', 'Invalid Post As User', {
@ -173,7 +180,7 @@ export const updateIncomingIntegration = async (
emoji: integration.emoji,
alias: integration.alias,
channel: channels,
...('username' in integration && { username: integration.username }),
...('username' in integration && { username: user.username, userId: user._id }),
...(isFrozen
? {}
: {
@ -188,6 +195,7 @@ export const updateIncomingIntegration = async (
_updatedBy: await Users.findOne({ _id: userId }, { projection: { username: 1 } }),
},
},
{ returnDocument: 'after' },
);
if (updatedIntegration) {

@ -106,6 +106,7 @@ export const updateOutgoingIntegration = async (
},
}),
},
{ returnDocument: 'after' },
);
if (updatedIntegration) {

@ -1,5 +1,6 @@
import type { Credentials } from '@rocket.chat/api-client';
import type { IIntegration, IMessage, IRoom, IUser } from '@rocket.chat/core-typings';
import { Random } from '@rocket.chat/random';
import { assert, expect } from 'chai';
import { after, before, describe, it } from 'mocha';
@ -606,6 +607,16 @@ describe('[Incoming Integrations]', () => {
});
describe('[/integrations.update]', () => {
let senderUser: IUser;
let sendUserCredentials: Credentials;
before(async () => {
senderUser = await createUser();
sendUserCredentials = await login(senderUser.username, password);
});
after(() => deleteUser(senderUser));
it('should update an integration by id and return the new data', (done) => {
void request
.put(api('integrations.update'))
@ -629,6 +640,7 @@ describe('[Incoming Integrations]', () => {
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');
integration = res.body.integration;
})
.end(done);
});
@ -649,6 +661,60 @@ describe('[Incoming Integrations]', () => {
})
.end(done);
});
it("should update an integration's username and associated userId correctly and return the new data", async () => {
await request
.put(api('integrations.update'))
.set(credentials)
.send({
type: 'webhook-incoming',
name: 'Incoming test updated x2',
enabled: true,
alias: 'test updated x2',
username: senderUser.username,
scriptEnabled: true,
overrideDestinationChannelEnabled: 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 x2');
expect(res.body.integration.alias).to.be.equal('test updated x2');
expect(res.body.integration.username).to.be.equal(senderUser.username);
expect(res.body.integration.userId).to.be.equal(sendUserCredentials['X-User-Id']);
integration = res.body.integration;
});
});
it('should send messages to the channel under the updated username', async () => {
const successfulMesssage = `Message sent successfully at #${Random.id()}`;
await request
.post(`/hooks/${integration._id}/${integration.token}`)
.send({
text: successfulMesssage,
})
.expect(200);
await request
.get(api('channels.messages'))
.set(credentials)
.query({
roomId: 'GENERAL',
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('messages').and.to.be.an('array');
const message = (res.body.messages as IMessage[]).find((m) => m.msg === successfulMesssage);
expect(message?.u).have.property('username', senderUser.username);
});
});
});
describe('[/integrations.remove]', () => {

Loading…
Cancel
Save