Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
6f3b0f6
refactor(core-typings): remove `_updatedAt` from `IInstanceStatus`
tassoevan Feb 3, 2026
75de5c4
refactor(core-typings): reset `_updatedAt` field on `ICustomSound`
tassoevan Feb 4, 2026
b19d90f
refactor(core-typings): reset `_updatedAt` field on `ICustomUserStatus`
tassoevan Feb 4, 2026
a0a2cbc
refactor(core-typings): delete `IInquiry`
tassoevan Feb 4, 2026
771c294
refactor(core-typings): reset `_updatedAt` field on `ILivechatBusines…
tassoevan Feb 4, 2026
2e7bb47
refactor(core-typings): reset `_updatedAt` field on `ILivechatDepartm…
tassoevan Feb 4, 2026
976855e
refactor: update `ICustomSoundsModel.setName` method to return the up…
tassoevan Feb 6, 2026
58e3958
refactor(core-typings): extend `ICronHistoryItem` to implement `IRock…
tassoevan Feb 6, 2026
32d8cae
refactor(core-typings): update `ISmarshHistory` to extend `IRocketCha…
tassoevan Feb 6, 2026
878a172
refactor(core-typings): extend `IEmailMessageHistory` to implement `I…
tassoevan Feb 6, 2026
e2d094d
refactor(core-typings,model-typings,models): implement `ICredentialTo…
tassoevan Feb 6, 2026
14e98de
refactor(core-typings): change `FederationKey` to interface and exten…
tassoevan Feb 6, 2026
fc190e9
refactor(core-typings): extend `IOAuthAuthCode` to implement `IRocket…
tassoevan Feb 6, 2026
2b7ef4c
refactor(core-typings): extend `IOAuthRefreshToken` to implement `IRo…
tassoevan Feb 6, 2026
825c663
refactor(core-typings): extend `IOAuthAccessToken` to implement `IRoc…
tassoevan Feb 7, 2026
51356d4
refactor(core-typings): update `IWorkspaceCredentials` to extend `IRo…
tassoevan Feb 7, 2026
2029fc8
refactor(core-typings): update `IReadReceipt` to extend `IRocketChatR…
tassoevan Feb 7, 2026
3bf153d
refactor(core-typings): update `IControl` to extend `IRocketChatRecord`
tassoevan Feb 7, 2026
ee89df0
refactor(core-typings): update `IPermission` to extend `IRocketChatRe…
tassoevan Feb 7, 2026
d27edb6
refactor(core-typings): update `IServerEvent` to extend `IRocketChatR…
tassoevan Feb 7, 2026
b8b8bec
refactor(core-typings,models): update `IOEmbedCache` to extend `IRock…
tassoevan Feb 7, 2026
c196cb4
refactor(core-typings): add `_updatedAt` field to role objects and up…
tassoevan Feb 7, 2026
1b805cf
refactor(core-typings): update `IStats` to extend `IRocketChatRecord`
tassoevan Feb 9, 2026
f3b9097
refactor(core-typings): update `IImportRecord` to extend `IRocketChat…
tassoevan Feb 9, 2026
6f6674f
refactor(core-typings): update `INotification` to extend `IRocketChat…
tassoevan Feb 9, 2026
6de07dd
refactor(core-typings): update `MessageReads` to extend `IRocketChatR…
tassoevan Feb 9, 2026
eeb5ba3
refactor(core-typings): update `IOAuthApps` to extend `IRocketChatRec…
tassoevan Feb 9, 2026
53b132c
refactor(core-typings): update `IBanner` and `IRocketChatRecord` to e…
tassoevan Feb 9, 2026
84f30d5
refactor(core-typings): update `IEmailInbox` to extend `IRocketChatRe…
tassoevan Feb 9, 2026
419eebe
refactor(core-typings): update `ISession` to extend `IRocketChatRecord`
tassoevan Feb 10, 2026
6876f99
refactor(core-typings): update `ILivechatTag` to extend `IRocketChatR…
tassoevan Feb 10, 2026
d299072
refactor(core-typings): update `IUpload` to extend `IRocketChatRecord`
tassoevan Feb 10, 2026
0fc5198
refactor(core-typings): remove redundant fields
tassoevan Feb 10, 2026
bde31e7
refactor(models): remove unnecessary JSDoc comment
tassoevan Feb 10, 2026
f1ae164
Merge branch 'develop' into refactor/optional-updated-at-field
tassoevan Feb 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,12 @@ Meteor.methods<ServerMethods>({
}

if (soundData.name !== soundData.previousName) {
await CustomSounds.setName(soundData._id, soundData.name);
void api.broadcast('notify.updateCustomSound', {
soundData: {
_id: soundData._id,
name: soundData.name,
extension: soundData.extension,
},
});
const updatedSound = await CustomSounds.setName(soundData._id, soundData.name);
if (updatedSound) {
void api.broadcast('notify.updateCustomSound', {
soundData: updatedSound,
});
}
}

return soundData._id;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { api } from '@rocket.chat/core-services';
import type { RequiredField } from '@rocket.chat/core-typings';
import type { ServerMethods } from '@rocket.chat/ddp-client';
import { CustomSounds } from '@rocket.chat/models';
import { Meteor } from 'meteor/meteor';

import type { ICustomSoundData } from './insertOrUpdateSound';
Expand Down Expand Up @@ -28,8 +29,13 @@ Meteor.methods<ServerMethods>({

return new Promise((resolve) => {
const ws = RocketChatFileCustomSoundsInstance.createWriteStream(`${soundData._id}.${soundData.extension}`, contentType);
ws.on('end', () => {
setTimeout(() => api.broadcast('notify.updateCustomSound', { soundData }), 500);
ws.on('end', async () => {
setTimeout(async () => {
const sound = await CustomSounds.findOneById(soundData._id);
if (sound) {
void api.broadcast('notify.updateCustomSound', { soundData: sound });
}
}, 500);
resolve();
});

Expand Down
10 changes: 5 additions & 5 deletions apps/meteor/app/file-upload/server/lib/FileUpload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ export const FileUpload = {
);
},

async resizeImagePreview(fileParam: IUpload) {
async resizeImagePreview(fileParam: Pick<IUpload, '_id'>) {
let file = await Uploads.findOneById(fileParam._id);
if (!file) {
return;
Expand All @@ -302,7 +302,7 @@ export const FileUpload = {
return sharp(await FileUpload.getBuffer(file)).metadata();
},

async createImageThumbnail(fileParam: IUpload) {
async createImageThumbnail(fileParam: Pick<IUpload, '_id' | 'identify'>) {
if (!settings.get('Message_Attachments_Thumbnails_Enabled')) {
return;
}
Expand Down Expand Up @@ -808,7 +808,7 @@ export class FileUploadClass {
}

private async _validateFile(
fileData: OptionalId<IUpload>,
fileData: Omit<OptionalId<IUpload>, '_updatedAt'>,
content: stream.Readable | Buffer | string,
): Promise<stream.Readable | Buffer | string> {
const filter = this.store.getFilter();
Expand All @@ -835,7 +835,7 @@ export class FileUploadClass {
}

async _doInsert(
fileData: OptionalId<IUpload>,
fileData: Omit<OptionalId<IUpload>, '_updatedAt'>,
content: stream.Readable | Buffer | string,
options?: { session?: ClientSession },
): Promise<IUpload> {
Expand All @@ -860,7 +860,7 @@ export class FileUploadClass {
}

async insert(
fileData: OptionalId<IUpload>,
fileData: Omit<OptionalId<IUpload>, '_updatedAt'>,
streamOrBuffer: stream.Readable | Buffer | string,
options?: { session?: ClientSession },
): Promise<IUpload> {
Expand Down
7 changes: 3 additions & 4 deletions apps/meteor/app/file-upload/ufs/AmazonS3/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import type { IUpload } from '@rocket.chat/core-typings';
import { Random } from '@rocket.chat/random';
import S3 from 'aws-sdk/clients/s3';
import { check } from 'meteor/check';
import type { OptionalId } from 'mongodb';
import _ from 'underscore';

import { SystemLogger } from '../../../../server/lib/logger/system';
Expand All @@ -25,11 +24,11 @@ export type S3Options = StoreOptions & {
region: string;
};
URLExpiryTimeSpan: number;
getPath: (file: OptionalId<IUpload>) => string;
getPath: (file: Omit<IUpload, '_updatedAt'>) => string;
};

class AmazonS3Store extends UploadFS.Store {
protected getPath: (file: IUpload) => string;
protected getPath: (file: Omit<IUpload, '_updatedAt'>) => string;

constructor(options: S3Options) {
// Default options
Expand Down Expand Up @@ -102,7 +101,7 @@ class AmazonS3Store extends UploadFS.Store {
}

file.AmazonS3 = {
path: classOptions.getPath(file),
path: classOptions.getPath(file as Omit<IUpload, '_updatedAt'>),
};

file.store = this.options.name; // assign store to file
Expand Down
7 changes: 3 additions & 4 deletions apps/meteor/app/file-upload/ufs/GoogleStorage/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Storage } from '@google-cloud/storage';
import type { IUpload } from '@rocket.chat/core-typings';
import { Random } from '@rocket.chat/random';
import { check } from 'meteor/check';
import type { OptionalId } from 'mongodb';

import { SystemLogger } from '../../../../server/lib/logger/system';
import { UploadFS } from '../../../../server/ufs';
Expand All @@ -19,11 +18,11 @@ type GStoreOptions = StoreOptions & {
};
bucket: string;
URLExpiryTimeSpan: number;
getPath: (file: OptionalId<IUpload>) => string;
getPath: (file: Omit<IUpload, '_updatedAt'>) => string;
};

class GoogleStorageStore extends UploadFS.Store {
protected getPath: (file: IUpload) => string;
protected getPath: (file: Omit<IUpload, '_updatedAt'>) => string;

constructor(options: GStoreOptions) {
super(options);
Expand Down Expand Up @@ -80,7 +79,7 @@ class GoogleStorageStore extends UploadFS.Store {
}

file.GoogleStorage = {
path: options.getPath(file),
path: options.getPath(file as Omit<IUpload, '_updatedAt'>),
};

file.store = this.options.name; // assign store to file
Expand Down
7 changes: 3 additions & 4 deletions apps/meteor/app/file-upload/ufs/Webdav/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import stream from 'stream';
import type { IUpload } from '@rocket.chat/core-typings';
import { Random } from '@rocket.chat/random';
import { check } from 'meteor/check';
import type { OptionalId } from 'mongodb';

import { SystemLogger } from '../../../../server/lib/logger/system';
import { UploadFS } from '../../../../server/ufs';
Expand All @@ -19,11 +18,11 @@ type WebdavOptions = StoreOptions & {
};
};
uploadFolderPath: string;
getPath: (file: OptionalId<IUpload>) => string;
getPath: (file: Omit<IUpload, '_updatedAt'>) => string;
};

class WebdavStore extends UploadFS.Store {
protected getPath: (file: IUpload) => string;
protected getPath: (file: Omit<IUpload, '_updatedAt'>) => string;

constructor(options: WebdavOptions) {
super(options);
Expand Down Expand Up @@ -72,7 +71,7 @@ class WebdavStore extends UploadFS.Store {
}

file.Webdav = {
path: options.getPath(file),
path: options.getPath(file as Omit<IUpload, '_updatedAt'>),
};

file.store = this.options.name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ export class RecordConverter<R extends IImportRecord, T extends RecordConverterO
data,
dataType: this.getDataType(),
options,
_updatedAt: new Date(),
});
}

Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/app/livechat/imports/server/rest/sms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { createRoom } from '../../../server/lib/rooms';

const logger = new Logger('SMS');

const getUploadFile = async (details: Omit<IUpload, '_id'>, fileUrl: string) => {
const getUploadFile = async (details: Omit<IUpload, '_id' | '_updatedAt'>, fileUrl: string) => {
const isSsrfSafe = await checkUrlForSsrf(fileUrl);
if (!isSsrfSafe) {
throw new Meteor.Error('error-invalid-url', 'Invalid URL');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { LivechatBusinessHourTypes } from '@rocket.chat/core-typings';
import moment from 'moment-timezone';
import { ObjectId } from 'mongodb';

export const createDefaultBusinessHourRow = (): ILivechatBusinessHour => {
export const createDefaultBusinessHourRow = (): Omit<ILivechatBusinessHour, '_updatedAt'> => {
const days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
const closedDays = ['Saturday', 'Sunday'];
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { ILivechatBusinessHour } from '@rocket.chat/core-typings';
import moment from 'moment';

export const filterBusinessHoursThatMustBeOpened = async (
businessHours: ILivechatBusinessHour[],
businessHours: Omit<ILivechatBusinessHour, '_updatedAt'>[],
): Promise<Pick<ILivechatBusinessHour, '_id' | 'type'>[]> => {
const currentTime = moment(moment().format('dddd:HH:mm:ss'), 'dddd:HH:mm:ss');

Expand Down
10 changes: 9 additions & 1 deletion apps/meteor/client/components/ImageGallery/ImageGallery.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,15 @@ const swiperStyle = css`
}
`;

export const ImageGallery = ({ images, onClose, loadMore }: { images: IUpload[]; onClose: () => void; loadMore?: () => void }) => {
export const ImageGallery = ({
images,
onClose,
loadMore,
}: {
images: Pick<IUpload, '_id' | 'path' | 'url'>[];
onClose: () => void;
loadMore?: () => void;
}) => {
const { t } = useTranslation();
const swiperRef = useRef<SwiperRef>(null);
const [, setSwiperInst] = useState<SwiperClass>();
Expand Down
10 changes: 5 additions & 5 deletions apps/meteor/client/hooks/useWorkspaceInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,15 @@ export const useWorkspaceInfo = ({ refreshStatistics }: { refreshStatistics?: bo
queryFn: () => getStatistics({ refresh: refreshStatistics ? 'true' : 'false' }),
staleTime: Infinity,
placeholderData: keepPreviousData,
select: (data: unknown) => {
const statsData = data as Serialized<IStats>;
select: (data: Serialized<IStats>): IStats => {
return {
...statsData,
lastMessageSentAt: statsData.lastMessageSentAt ? new Date(statsData.lastMessageSentAt) : undefined,
...data,
lastMessageSentAt: data.lastMessageSentAt ? new Date(data.lastMessageSentAt) : undefined,
_updatedAt: new Date(data._updatedAt),
};
},
},
],
] as const,
});
};

Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/client/lib/userStatuses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export class UserStatuses implements Iterable<UserStatusDescriptor> {
this.store.set(customUserStatus.id, customUserStatus);
}

public createFromCustom(customUserStatus: ICustomUserStatus): UserStatusDescriptor {
public createFromCustom(customUserStatus: Omit<ICustomUserStatus, '_updatedAt'>): UserStatusDescriptor {
if (!this.isValidType(customUserStatus.statusType)) {
throw new Error('Invalid user status type');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const CustomSoundProvider = ({ children }: CustomSoundProviderProps) => {
const { notificationsSoundVolume, voipRingerVolume } = useUserSoundPreferences();

const { data: list } = useQuery({
queryFn: async () => {
queryFn: async (): Promise<Omit<ICustomSound, '_updatedAt'>[]> => {
const customSoundsList = await sdk.call('listCustomSounds');
if (!customSoundsList.length) {
return defaultSounds;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const soundTranslationKeys: Record<string, string> = {
'ringtone': 'Sound_Ringtone',
};

export const defaultSounds: ICustomSound[] = [
export const defaultSounds: Omit<ICustomSound, '_updatedAt'>[] = [
{ _id: 'chime', name: 'Sound_Chime', extension: 'mp3', src: getAssetUrl('sounds/chime.mp3') },
{ _id: 'door', name: 'Sound_Door', extension: 'mp3', src: getAssetUrl('sounds/door.mp3') },
{ _id: 'beep', name: 'Sound_Beep', extension: 'mp3', src: getAssetUrl('sounds/beep.mp3') },
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/client/startup/roles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Meteor.startup(() => {
onLoggedIn(async () => {
const { roles } = await sdk.rest.get('/v1/roles.list');
// if a role is checked before this collection is populated, it will return undefined
Roles.state.replaceAll(roles);
Roles.state.replaceAll(roles.map((role) => ({ ...role, _updatedAt: new Date(role._updatedAt) })));
});

type ClientAction = 'inserted' | 'updated' | 'removed' | 'changed';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,15 @@ const roles: IRole[] = [
protected: true,
scope: 'Users',
_id: 'owner',
_updatedAt: new Date(),
},
{
description: 'Administrator',
name: 'admin',
protected: true,
scope: 'Users',
_id: 'admin',
_updatedAt: new Date(),
},
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,55 +24,63 @@ const roles: IRole[] = [
protected: true,
scope: 'Users',
_id: 'owner',
_updatedAt: new Date(),
},
{
description: 'Administrator',
name: 'admin',
protected: true,
scope: 'Users',
_id: 'admin',
_updatedAt: new Date(),
},
{
description: 'Leader',
name: 'leader',
protected: false,
scope: 'Subscriptions',
_id: 'leader',
_updatedAt: new Date(),
},
{
description: 'Moderator',
name: 'moderator',
protected: false,
scope: 'Subscriptions',
_id: 'moderator',
_updatedAt: new Date(),
},
{
description: 'User',
name: 'user',
protected: true,
scope: 'Users',
_id: 'user',
_updatedAt: new Date(),
},
{
description: 'Guest',
name: 'guest',
protected: true,
scope: 'Users',
_id: 'guest',
_updatedAt: new Date(),
},
{
description: 'Bot',
name: 'bot',
protected: true,
scope: 'Users',
_id: 'bot',
_updatedAt: new Date(),
},
{
description: 'App',
name: 'app',
protected: true,
scope: 'Users',
_id: 'app',
_updatedAt: new Date(),
},
];

Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/client/views/admin/users/AdminUserForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ type AdminUserFormProps = {
onReload: () => void;
context: string;
refetchUserFormData?: () => void;
roleData: { roles: IRole[] } | undefined;
roleData: { roles: Serialized<IRole>[] } | undefined;
roleError: Error | null;
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { IRole, IUser } from '@rocket.chat/core-typings';
import type { IRole, IUser, Serialized } from '@rocket.chat/core-typings';
import { Box, Callout } from '@rocket.chat/fuselage';
import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
import type { ReactElement } from 'react';
Expand All @@ -12,7 +12,7 @@ type AdminUserFormWithDataProps = {
uid: IUser['_id'];
onReload: () => void;
context: string;
roleData: { roles: IRole[] } | undefined;
roleData: { roles: Serialized<IRole>[] } | undefined;
roleError: Error | null;
};

Expand Down
Loading
Loading