Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
22 changes: 21 additions & 1 deletion apps/meteor/app/api/server/v1/calendar.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Calendar } from '@rocket.chat/core-services';
import {
isCalendarEventSearchProps,
isCalendarEventListProps,
isCalendarEventCreateProps,
isCalendarEventImportProps,
Expand All @@ -25,6 +26,25 @@ API.v1.addRoute(
},
);

API.v1.addRoute(
'calendar-events.search',
{
authRequired: true,
validateParams: isCalendarEventSearchProps,
rateLimiterOptions: { numRequestsAllowed: 3, intervalTimeInMS: 1000 },
},
{
async get() {
const { userId } = this;
const { text } = this.queryParams;

const data = await Calendar.searchBySubject(userId, text);
return API.v1.success({ data });
},
},
);


API.v1.addRoute(
'calendar-events.info',
{ authRequired: true, validateParams: isCalendarEventInfoProps, rateLimiterOptions: { numRequestsAllowed: 3, intervalTimeInMS: 1000 } },
Expand Down Expand Up @@ -142,4 +162,4 @@ API.v1.addRoute(
return API.v1.success();
},
},
);
);
12 changes: 12 additions & 0 deletions apps/meteor/server/services/calendar/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,18 @@ export class CalendarService extends ServiceClassInternal implements ICalendarSe
return event._id;
}

public async searchBySubject(uid: IUser['_id'], text: string): Promise<ICalendarEvent[]> {
if (!text?.trim()) {
return [];
}

return CalendarEvent.findBySubject(uid, text, {
limit: 50,
}).toArray();
}



public async get(eventId: ICalendarEvent['_id']): Promise<ICalendarEvent | null> {
return CalendarEvent.findOne({ _id: eventId });
}
Expand Down
3 changes: 2 additions & 1 deletion packages/core-services/src/types/ICalendarService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ export interface ICalendarService {
import(data: Omit<InsertionModel<ICalendarEvent>, 'notificationSent'>): Promise<ICalendarEvent['_id']>;
get(eventId: ICalendarEvent['_id']): Promise<ICalendarEvent | null>;
list(uid: IUser['_id'], date: Date): Promise<ICalendarEvent[]>;
searchBySubject(uid: IUser['_id'], text: string): Promise<ICalendarEvent[]>;
update(eventId: ICalendarEvent['_id'], data: Partial<ICalendarEvent>): Promise<UpdateResult | null>;
delete(eventId: ICalendarEvent['_id']): Promise<DeleteResult>;
setupNextNotification(): Promise<void>;
setupNextStatusChange(): Promise<void>;
cancelUpcomingStatusChanges(uid: IUser['_id'], endTime?: Date): Promise<void>;
}
}
20 changes: 19 additions & 1 deletion packages/models/src/models/CalendarEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import type { FindCursor, IndexDescription, Collection, Db, UpdateResult } from

import { BaseRaw } from './BaseRaw';

function escapeRegExp(text: string): string {
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Duplicate escapeRegExp utility: should import from '@rocket.chat/string-helpers'

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/models/src/models/CalendarEvent.ts, line 7:

<comment>Duplicate escapeRegExp utility: should import from '@rocket.chat/string-helpers'</comment>

<file context>
@@ -4,6 +4,10 @@ import type { FindCursor, IndexDescription, Collection, Db, UpdateResult } from
 
 import { BaseRaw } from './BaseRaw';
 
+function escapeRegExp(text: string): string {
+	return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+}
</file context>
Fix with Cubic

return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}

export class CalendarEventRaw extends BaseRaw<ICalendarEvent> implements ICalendarEventModel {
constructor(db: Db, trash?: Collection<RocketChatRecordDeleted<ICalendarEvent>>) {
super(db, 'calendar_event', trash);
Expand Down Expand Up @@ -48,6 +52,20 @@ export class CalendarEventRaw extends BaseRaw<ICalendarEvent> implements ICalend
);
}

public findBySubject(uid: IUser['_id'], text: string): FindCursor<ICalendarEvent> {
const escapedText = escapeRegExp(text);

return this.find(
{
uid,
subject: { $regex: escapedText, $options: 'i' },
},
{
sort: { startTime: 1 },
},
);
}

public async updateEvent(
eventId: ICalendarEvent['_id'],
{
Expand Down Expand Up @@ -257,4 +275,4 @@ export class CalendarEventRaw extends BaseRaw<ICalendarEvent> implements ICalend
},
);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { JSONSchemaType } from 'ajv';
import { ajv } from '../../Ajv';

export type CalendarEventSearchProps = {
text: string;
};

const calendarEventSearchPropsSchema: JSONSchemaType<CalendarEventSearchProps> = {
type: 'object',
properties: {
text: {
type: 'string',
nullable: false,
},
},
required: ['text'],
additionalProperties: false,
};

export const isCalendarEventSearchProps = ajv.compile(calendarEventSearchPropsSchema);
8 changes: 7 additions & 1 deletion packages/rest-typings/src/v1/calendar/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import type { CalendarEventImportProps } from './CalendarEventImportProps';
import type { CalendarEventInfoProps } from './CalendarEventInfoProps';
import type { CalendarEventListProps } from './CalendarEventListProps';
import type { CalendarEventUpdateProps } from './CalendarEventUpdateProps';
import type { CalendarEventSearchProps } from './CalendarEventSearchProps';

export * from './CalendarEventCreateProps';
export * from './CalendarEventDeleteProps';
export * from './CalendarEventImportProps';
export * from './CalendarEventInfoProps';
export * from './CalendarEventUpdateProps';
export * from './CalendarEventListProps';
export * from './CalendarEventSearchProps';

export type CalendarEndpoints = {
'/v1/calendar-events.create': {
Expand All @@ -38,4 +40,8 @@ export type CalendarEndpoints = {
'/v1/calendar-events.delete': {
POST: (params: CalendarEventDeleteProps) => void;
};
};

'/v1/calendar-events.search': {
GET: (params: CalendarEventSearchProps) => { data: ICalendarEvent[] };
};
};