Skip to content

Commit

Permalink
Merge branch 'develop' into lingohub_language_update_2023-10-10Z
Browse files Browse the repository at this point in the history
  • Loading branch information
kodiakhq[bot] authored Oct 11, 2023
2 parents 2a4ec20 + 3650ab8 commit f107773
Show file tree
Hide file tree
Showing 10 changed files with 283 additions and 69 deletions.
5 changes: 5 additions & 0 deletions .changeset/lucky-vans-develop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rocket.chat/meteor": patch
---

Fixed issue with file attachments in rooms' messages export having no content
5 changes: 5 additions & 0 deletions .changeset/wicked-jars-double.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rocket.chat/meteor": patch
---

Handle the username update in the background
11 changes: 7 additions & 4 deletions apps/meteor/app/file-upload/server/config/AmazonS3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,15 @@ const get: FileUploadClass['get'] = async function (this: FileUploadClass, file,

const copy: FileUploadClass['copy'] = async function (this: FileUploadClass, file, out) {
const fileUrl = await this.store.getRedirectURL(file);
if (fileUrl) {
const request = /^https:/.test(fileUrl) ? https : http;
request.get(fileUrl, (fileRes) => fileRes.pipe(out));
} else {
if (!fileUrl) {
out.end();
return;
}

const request = /^https:/.test(fileUrl) ? https : http;
return new Promise((resolve) => {
request.get(fileUrl, (fileRes) => fileRes.pipe(out).on('finish', () => resolve()));
});
};

const AmazonS3Uploads = new FileUploadClass({
Expand Down
11 changes: 7 additions & 4 deletions apps/meteor/app/file-upload/server/config/GoogleStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,15 @@ const get: FileUploadClass['get'] = async function (this: FileUploadClass, file,
const copy: FileUploadClass['copy'] = async function (this: FileUploadClass, file, out) {
const fileUrl = await this.store.getRedirectURL(file, false);

if (fileUrl) {
const request = /^https:/.test(fileUrl) ? https : http;
request.get(fileUrl, (fileRes) => fileRes.pipe(out));
} else {
if (!fileUrl) {
out.end();
return;
}

const request = /^https:/.test(fileUrl) ? https : http;
return new Promise((resolve) => {
request.get(fileUrl, (fileRes) => fileRes.pipe(out).on('finish', () => resolve()));
});
};

const GoogleCloudStorageUploads = new FileUploadClass({
Expand Down
4 changes: 3 additions & 1 deletion apps/meteor/app/file-upload/server/config/Webdav.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ const get: FileUploadClass['get'] = async function (this: FileUploadClass, file,
};

const copy: FileUploadClass['copy'] = async function (this: FileUploadClass, file, out) {
(await this.store.getReadStream(file._id, file)).pipe(out);
return new Promise(async (resolve) => {
(await this.store.getReadStream(file._id, file)).pipe(out).on('finish', () => resolve());
});
};

const WebdavUploads = new FileUploadClass({
Expand Down
1 change: 1 addition & 0 deletions apps/meteor/app/lib/server/functions/saveUser.js
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ export const saveUser = async function (userId, userData) {
_id: userData._id,
username: userData.username,
name: userData.name,
updateUsernameInBackground: true,
}))
) {
throw new Meteor.Error('error-could-not-save-identity', 'Could not save user identity', {
Expand Down
129 changes: 93 additions & 36 deletions apps/meteor/app/lib/server/functions/saveUserIdentity.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { IUser } from '@rocket.chat/core-typings';
import { Messages, VideoConference, LivechatDepartmentAgents, Rooms, Subscriptions, Users } from '@rocket.chat/models';

import { SystemLogger } from '../../../../server/lib/logger/system';
import { FileUpload } from '../../../file-upload/server';
import { _setRealName } from './setRealName';
import { _setUsername } from './setUsername';
Expand All @@ -11,7 +13,17 @@ import { validateName } from './validateName';
* @param {object} changes changes to the user
*/

export async function saveUserIdentity({ _id, name: rawName, username: rawUsername }: { _id: string; name?: string; username?: string }) {
export async function saveUserIdentity({
_id,
name: rawName,
username: rawUsername,
updateUsernameInBackground = false,
}: {
_id: string;
name?: string;
username?: string;
updateUsernameInBackground?: boolean; // TODO: remove this
}) {
if (!_id) {
return false;
}
Expand Down Expand Up @@ -48,46 +60,91 @@ export async function saveUserIdentity({ _id, name: rawName, username: rawUserna

// if coming from old username, update all references
if (previousUsername) {
if (usernameChanged && typeof rawUsername !== 'undefined') {
const fileStore = FileUpload.getStore('Avatars');
const previousFile = await fileStore.model.findOneByName(previousUsername);
const file = await fileStore.model.findOneByName(username);
if (file) {
await fileStore.model.deleteFile(file._id);
}
if (previousFile) {
await fileStore.model.updateFileNameById(previousFile._id, username);
}

await Messages.updateAllUsernamesByUserId(user._id, username);
await Messages.updateUsernameOfEditByUserId(user._id, username);

const cursor = Messages.findByMention(previousUsername);
for await (const msg of cursor) {
const updatedMsg = msg.msg.replace(new RegExp(`@${previousUsername}`, 'ig'), `@${username}`);
await Messages.updateUsernameAndMessageOfMentionByIdAndOldUsername(msg._id, previousUsername, username, updatedMsg);
}

await Rooms.replaceUsername(previousUsername, username);
await Rooms.replaceMutedUsername(previousUsername, username);
await Rooms.replaceUsernameOfUserByUserId(user._id, username);
await Subscriptions.setUserUsernameByUserId(user._id, username);

await LivechatDepartmentAgents.replaceUsernameOfAgentByUserId(user._id, username);
const handleUpdateParams = {
username,
previousUsername,
rawUsername,
usernameChanged,
user,
name,
previousName,
rawName,
nameChanged,
};
if (updateUsernameInBackground) {
setImmediate(async () => {
try {
await updateUsernameReferences(handleUpdateParams);
} catch (err) {
SystemLogger.error(err);
}
});
} else {
await updateUsernameReferences(handleUpdateParams);
}
}

return true;
}

// update other references if either the name or username has changed
if (usernameChanged || nameChanged) {
// update name and fname of 1-on-1 direct messages
await Subscriptions.updateDirectNameAndFnameByName(previousUsername, rawUsername && username, rawName && name);
async function updateUsernameReferences({
username,
previousUsername,
rawUsername,
usernameChanged,
user,
name,
previousName,
rawName,
nameChanged,
}: {
username: string;
previousUsername: string;
rawUsername?: string;
usernameChanged: boolean;
user: IUser;
name: string;
previousName: string | undefined;
rawName?: string;
nameChanged: boolean;
}): Promise<void> {
if (usernameChanged && typeof rawUsername !== 'undefined') {
const fileStore = FileUpload.getStore('Avatars');
const previousFile = await fileStore.model.findOneByName(previousUsername);
const file = await fileStore.model.findOneByName(username);
if (file) {
await fileStore.model.deleteFile(file._id);
}
if (previousFile) {
await fileStore.model.updateFileNameById(previousFile._id, username);
}

// update name and fname of group direct messages
await updateGroupDMsName(user);
await Messages.updateAllUsernamesByUserId(user._id, username);
await Messages.updateUsernameOfEditByUserId(user._id, username);

// update name and username of users on video conferences
await VideoConference.updateUserReferences(user._id, username || previousUsername, name || previousName);
const cursor = Messages.findByMention(previousUsername);
for await (const msg of cursor) {
const updatedMsg = msg.msg.replace(new RegExp(`@${previousUsername}`, 'ig'), `@${username}`);
await Messages.updateUsernameAndMessageOfMentionByIdAndOldUsername(msg._id, previousUsername, username, updatedMsg);
}

await Rooms.replaceUsername(previousUsername, username);
await Rooms.replaceMutedUsername(previousUsername, username);
await Rooms.replaceUsernameOfUserByUserId(user._id, username);
await Subscriptions.setUserUsernameByUserId(user._id, username);

await LivechatDepartmentAgents.replaceUsernameOfAgentByUserId(user._id, username);
}

return true;
// update other references if either the name or username has changed
if (usernameChanged || nameChanged) {
// update name and fname of 1-on-1 direct messages
await Subscriptions.updateDirectNameAndFnameByName(previousUsername, rawUsername && username, rawName && name);

// update name and fname of group direct messages
await updateGroupDMsName(user);

// update name and username of users on video conferences
await VideoConference.updateUserReferences(user._id, username || previousUsername, name || previousName);
}
}
4 changes: 3 additions & 1 deletion apps/meteor/server/lib/dataExport/sendFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,11 @@ export const sendFile = async (data: ExportFile, user: IUser): Promise<void> =>

await exportMessages();

const promises: Promise<void>[] = [];
for await (const attachmentData of fullFileList) {
await copyFileUpload(attachmentData, assetsPath);
promises.push(copyFileUpload(attachmentData, assetsPath));
}
await Promise.all(promises);

const exportFile = `${baseDir}-export.zip`;
await makeZipFile(exportPath, exportFile);
Expand Down
48 changes: 25 additions & 23 deletions apps/meteor/tests/end-to-end/api/09-rooms.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import path from 'path';
import { expect } from 'chai';
import { after, afterEach, before, beforeEach, describe, it } from 'mocha';

import { sleep } from '../../../lib/utils/sleep';
import { getCredentials, api, request, credentials } from '../../data/api-data.js';
import { sendSimpleMessage, deleteMessage } from '../../data/chat.helper';
import { imgURL } from '../../data/interactions.js';
Expand Down Expand Up @@ -1543,29 +1544,30 @@ describe('[Rooms]', function () {
roomId = result.body.room.rid;
});

it('should update group name if user changes username', (done) => {
updateSetting('UI_Use_Real_Name', false).then(() => {
request
.post(api('users.update'))
.set(credentials)
.send({
userId: testUser._id,
data: {
username: `changed.username.${testUser.username}`,
},
})
.end(() => {
request
.get(api('subscriptions.getOne'))
.set(credentials)
.query({ roomId })
.end((err, res) => {
const { subscription } = res.body;
expect(subscription.name).to.equal(`rocket.cat,changed.username.${testUser.username}`);
done();
});
});
});
it('should update group name if user changes username', async () => {
await updateSetting('UI_Use_Real_Name', false);
await request
.post(api('users.update'))
.set(credentials)
.send({
userId: testUser._id,
data: {
username: `changed.username.${testUser.username}`,
},
});

// need to wait for the username update finish
await sleep(300);

await request
.get(api('subscriptions.getOne'))
.set(credentials)
.query({ roomId })
.send()
.expect((res) => {
const { subscription } = res.body;
expect(subscription.name).to.equal(`rocket.cat,changed.username.${testUser.username}`);
});
});

it('should update group name if user changes name', (done) => {
Expand Down
Loading

0 comments on commit f107773

Please sign in to comment.