Skip to content

fix(search): escape regex in from and mention filters for exact username matching#39942

Open
sharanyamahajan wants to merge 5 commits intoRocketChat:developfrom
sharanyamahajan:refactor/usercard-linebreak-cleanup
Open

fix(search): escape regex in from and mention filters for exact username matching#39942
sharanyamahajan wants to merge 5 commits intoRocketChat:developfrom
sharanyamahajan:refactor/usercard-linebreak-cleanup

Conversation

@sharanyamahajan
Copy link
Copy Markdown

@sharanyamahajan sharanyamahajan commented Mar 29, 2026

Proposed changes (including videos or screenshots)

This PR fixes incorrect message search results when using from: and mention: filters with usernames containing regex special characters (e.g., dots).

Currently, usernames are directly inserted into MongoDB $regex queries without escaping. This causes special characters like . to act as wildcards, leading to unintended matches.

Example:

  • Searching from:rocket.cat also matches rocketXcat, rocket_cat, etc.

Changes made:

  • Escaped usernames using escapeRegExp before constructing regex
  • Added ^ and $ anchors to enforce exact username matching
  • Applied fixes to both from: and mention: filters in parseMessageSearchQuery.ts
  • Fixed a minor bug in consumeAfter where an incorrect variable (beforeDate) was referenced

Result:

  • Accurate message filtering by exact username
  • No unintended matches due to regex wildcard behavior

Issue(s)

Fixes #39927

Steps to test or reproduce

  1. Create two users:
    • rocket.cat
    • rocketXcat
  2. Send messages from both users in a channel
  3. Use message search:

Summary by CodeRabbit

  • Style

    • Removed unnecessary whitespace formatting in component files.
  • Refactor

    • Enhanced message search query parsing with improved username and mention matching.
    • Simplified search result sorting options.
    • Updated message text search processing to use text-based search exclusively.

Added a new line to app.json to improve configuration consistency.
Changes-
1. Updated app.json
2. Added the required configuration line
Notes-This is a minor configuration update and does not affect application functionality.
Removed unnecessary line breaks in the UserCard component to improve code readability and maintain formatting consistency. No functional changes were introduced.
@sharanyamahajan sharanyamahajan requested review from a team as code owners March 29, 2026 10:31
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 29, 2026

⚠️ No Changeset found

Latest commit: 4a7020c

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@dionisio-bot
Copy link
Copy Markdown
Contributor

dionisio-bot bot commented Mar 29, 2026

Looks like this PR is not ready to merge, because of the following issues:

  • This PR is missing the 'stat: QA assured' label
  • This PR is missing the required milestone or project

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 29, 2026

Walkthrough

This change fixes a message search bug where filters for usernames containing dots (e.g., rocket.cat) match unintended usernames due to unescaped regex patterns. It updates the username/mention regex construction to properly escape and anchor patterns, while refactoring and simplifying related parsing logic.

Changes

Cohort / File(s) Summary
Formatting cleanup
apps/meteor/client/components/UserCard/UserCard.tsx
Removed superfluous blank lines around type and component definitions. No functional changes.
Message search parsing refactor
apps/meteor/server/lib/parseMessageSearchQuery.ts
Fixed regex escaping for from: and mention: filters by wrapping each username with ^...$ anchors via escapeRegExp. Removed block comments, simplified object literals, tightened empty-string handling, simplified order parsing to only accept asc|desc, and removed regex-based message-text modes. Changed exported function signature from typed destructured options to untyped options: any.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

type: bug

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Out of Scope Changes check ❓ Inconclusive The UserCard.tsx change (removing blank lines) is outside the linked issue scope, but the primary changes to parseMessageSearchQuery.ts directly address #39927's regex escaping requirements. Verify whether the UserCard.tsx formatting changes are intentional and scoped, or should be moved to a separate cleanup PR for better traceability.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: escaping regex in from and mention filters for exact username matching, which is the primary fix in parseMessageSearchQuery.ts.
Linked Issues check ✅ Passed The PR directly addresses #39927 by escaping usernames with escapeRegExp, adding ^ and $ anchors for exact matching in both from: and mention: filters, preventing regex metacharacters from acting as wildcards.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (4)
apps/meteor/server/lib/parseMessageSearchQuery.ts (4)

58-58: Remove implementation comment.

As per coding guidelines, avoid code comments in the implementation.

Suggested fix
-	// ✅ FIXED
 	private consumeMention(text: string) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/server/lib/parseMessageSearchQuery.ts` at line 58, Remove the
implementation comment "// ✅ FIXED" from the parseMessageSearchQuery module so
the function/implementation (parseMessageSearchQuery) contains no inline
implementation comments; edit the source to delete that comment line and ensure
no other implementation-only comments remain in the same function or surrounding
scope.

243-245: Avoid any type; use proper typing for options parameter.

Using any removes type safety. The constructor already defines the expected shape. Extract the type or use the constructor's parameter type.

Suggested fix
-export function parseMessageSearchQuery(text: string, options: any) {
+export function parseMessageSearchQuery(
+	text: string,
+	options: {
+		user?: IUser;
+		offset?: number;
+		limit?: number;
+		forceRegex?: boolean;
+	},
+) {
 	const parser = new MessageSearchQueryParser(options);
 	return parser.parse(text);
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/server/lib/parseMessageSearchQuery.ts` around lines 243 - 245,
The parseMessageSearchQuery function currently types its options parameter as
any; change it to the concrete type expected by MessageSearchQueryParser's
constructor (use the parser's constructor parameter type or exported interface
used by MessageSearchQueryParser) so callers get proper typing. Update the
signature of parseMessageSearchQuery(text: string, options: /* use
MessageSearchQueryParser constructor param type */) and any related declarations
to import or reference that type from where MessageSearchQueryParser is defined,
ensuring type compatibility with new MessageSearchQueryParser(options).

201-206: Add private modifier for consistency.

All other consume* methods are marked private, but consumeOrder is missing this modifier.

Suggested fix
-	consumeOrder(text: string) {
+	private consumeOrder(text: string) {
 		return text.replace(/(?:order|sort):(asc|desc)/g, (_: string, direction: string) => {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/server/lib/parseMessageSearchQuery.ts` around lines 201 - 206,
The method consumeOrder is missing the private visibility modifier while all
other consume* methods are private; make consumeOrder a private method by adding
the private modifier to its declaration (i.e., change the consumeOrder(...)
signature to private consumeOrder(...)) so it matches the other consume* methods
and class encapsulation.

165-165: Remove implementation comment.

As per coding guidelines, avoid code comments in the implementation.

Suggested fix
-	// ✅ FIXED BUG HERE
 	private consumeAfter(text: string) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/server/lib/parseMessageSearchQuery.ts` at line 165, Remove the
implementation comment "// ✅ FIXED BUG HERE" from
apps/meteor/server/lib/parseMessageSearchQuery.ts so the codebase follows the
guideline to avoid inline implementation comments; locate the comment in the
parseMessageSearchQuery function (or top-level body of that module) and delete
it, leaving only executable code and any necessary explanatory JSDoc or
function-level comments.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/meteor/server/lib/parseMessageSearchQuery.ts`:
- Around line 208-216: The class stores a forceRegex flag in the constructor but
consumeMessageText always sets a $text search and ignores it; either remove
forceRegex or honor it: update consumeMessageText in ParseMessageSearchQuery (or
the class where forceRegex is defined) to check this.forceRegex (or the
constructor param name) and when true build a regex-based query (e.g., set
this.query.text or this.query.$or with RegExp on message text) instead of
setting this.query.$text and projection, otherwise retain the existing $text
branch; alternatively, if regex support is intentionally dropped, remove the
forceRegex property and its constructor parameter and any callers that pass
Message_AlwaysSearchRegExp.

---

Nitpick comments:
In `@apps/meteor/server/lib/parseMessageSearchQuery.ts`:
- Line 58: Remove the implementation comment "// ✅ FIXED" from the
parseMessageSearchQuery module so the function/implementation
(parseMessageSearchQuery) contains no inline implementation comments; edit the
source to delete that comment line and ensure no other implementation-only
comments remain in the same function or surrounding scope.
- Around line 243-245: The parseMessageSearchQuery function currently types its
options parameter as any; change it to the concrete type expected by
MessageSearchQueryParser's constructor (use the parser's constructor parameter
type or exported interface used by MessageSearchQueryParser) so callers get
proper typing. Update the signature of parseMessageSearchQuery(text: string,
options: /* use MessageSearchQueryParser constructor param type */) and any
related declarations to import or reference that type from where
MessageSearchQueryParser is defined, ensuring type compatibility with new
MessageSearchQueryParser(options).
- Around line 201-206: The method consumeOrder is missing the private visibility
modifier while all other consume* methods are private; make consumeOrder a
private method by adding the private modifier to its declaration (i.e., change
the consumeOrder(...) signature to private consumeOrder(...)) so it matches the
other consume* methods and class encapsulation.
- Line 165: Remove the implementation comment "// ✅ FIXED BUG HERE" from
apps/meteor/server/lib/parseMessageSearchQuery.ts so the codebase follows the
guideline to avoid inline implementation comments; locate the comment in the
parseMessageSearchQuery function (or top-level body of that module) and delete
it, leaving only executable code and any necessary explanatory JSDoc or
function-level comments.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 04784f7b-a95c-43c8-bba0-3bdcf10caa5c

📥 Commits

Reviewing files that changed from the base of the PR and between 4235cd9 and 4a7020c.

📒 Files selected for processing (2)
  • apps/meteor/client/components/UserCard/UserCard.tsx
  • apps/meteor/server/lib/parseMessageSearchQuery.ts
💤 Files with no reviewable changes (1)
  • apps/meteor/client/components/UserCard/UserCard.tsx
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • apps/meteor/server/lib/parseMessageSearchQuery.ts
🧠 Learnings (7)
📓 Common learnings
Learnt from: smirk-dev
Repo: RocketChat/Rocket.Chat PR: 39625
File: apps/meteor/app/api/server/v1/push.ts:85-97
Timestamp: 2026-03-14T14:58:58.834Z
Learning: In RocketChat/Rocket.Chat, the `push.token` POST/DELETE endpoints in `apps/meteor/app/api/server/v1/push.ts` were already migrated to the chained router API pattern on `develop` prior to PR `#39625`. `cleanTokenResult` (which strips `authToken` and returns `PushTokenResult`) and `isPushTokenPOSTProps`/`isPushTokenDELETEProps` validators already exist on `develop`. PR `#39625` only migrates `push.get` and `push.info` to the chained pattern. Do not flag `cleanTokenResult` or `PushTokenResult` as newly introduced behavior-breaking changes when reviewing this PR.
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38262
File: apps/meteor/client/lib/utils/normalizeMessagePreview/getMessagePreview.ts:24-33
Timestamp: 2026-01-19T18:17:46.433Z
Learning: In the Rocket.Chat repository, usernames (lastMessage.u.username) and display names (lastMessage.u.name) are sanitized/escaped centrally elsewhere in the system, so individual display functions like getMessagePreview do not need to escape these values before interpolating them into strings.
Learnt from: ggazzo
Repo: RocketChat/Rocket.Chat PR: 35995
File: apps/meteor/app/api/server/v1/rooms.ts:1107-1112
Timestamp: 2026-02-23T17:53:18.785Z
Learning: In Rocket.Chat PR reviews, maintain strict scope boundaries—when a PR is focused on a specific endpoint (e.g., rooms.favorite), avoid reviewing or suggesting changes to other endpoints that were incidentally refactored (e.g., rooms.invite) unless explicitly requested by maintainers.
📚 Learning: 2026-03-16T23:33:15.721Z
Learnt from: amitb0ra
Repo: RocketChat/Rocket.Chat PR: 39676
File: apps/meteor/app/api/server/v1/users.ts:862-869
Timestamp: 2026-03-16T23:33:15.721Z
Learning: In RocketChat/Rocket.Chat OpenAPI migration PRs (e.g., PR `#39676` for users.register in apps/meteor/app/api/server/v1/users.ts), calls to `this.parseJsonQuery()` inside migrated handlers are intentionally preserved without adding a corresponding `query` AJV schema to the route options. Adding query-param schemas for the `fields`/`sort`/`query` parameters consumed by `parseJsonQuery()` is a separate cross-cutting concern shared by many endpoints (e.g., users.create, users.update, users.list) and is explicitly out of scope for individual endpoint migration PRs. Do not flag the absence of a `query` schema for `parseJsonQuery()` usage as a violation of OpenAPI/AJV contract during migration reviews.

Applied to files:

  • apps/meteor/server/lib/parseMessageSearchQuery.ts
📚 Learning: 2026-03-03T11:11:48.541Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 39230
File: apps/meteor/app/api/server/v1/chat.ts:214-222
Timestamp: 2026-03-03T11:11:48.541Z
Learning: In apps/meteor/server/lib/moderation/reportMessage.ts, the reportMessage function validates that description is not empty or whitespace-only with `if (!description.trim())`. When migrating the chat.reportMessage endpoint to OpenAPI, adding minLength validation to the schema preserves this existing behavior.

Applied to files:

  • apps/meteor/server/lib/parseMessageSearchQuery.ts
📚 Learning: 2026-01-17T01:51:47.764Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38219
File: packages/core-typings/src/cloud/Announcement.ts:5-6
Timestamp: 2026-01-17T01:51:47.764Z
Learning: In packages/core-typings/src/cloud/Announcement.ts, the AnnouncementSchema.createdBy field intentionally overrides IBannerSchema.createdBy (object with _id and optional username) with a string enum ['cloud', 'system'] to match existing runtime behavior. This is documented as technical debt with a FIXME comment at apps/meteor/app/cloud/server/functions/syncWorkspace/handleCommsSync.ts:53 and should not be flagged as an error until the runtime behavior is corrected.

Applied to files:

  • apps/meteor/server/lib/parseMessageSearchQuery.ts
📚 Learning: 2026-02-24T19:09:09.561Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38974
File: apps/meteor/app/api/server/v1/im.ts:220-221
Timestamp: 2026-02-24T19:09:09.561Z
Learning: In RocketChat/Rocket.Chat OpenAPI migration PRs for apps/meteor/app/api/server/v1 endpoints, maintainers prefer to avoid any logic changes; style-only cleanups (like removing inline comments) may be deferred to follow-ups to keep scope tight.

Applied to files:

  • apps/meteor/server/lib/parseMessageSearchQuery.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In the Rocket.Chat repository, do not reference Biome lint rules in code review feedback. Biome is not used even if biome.json exists; only reference Biome rules if there is explicit, project-wide usage documented. For TypeScript files, review lint implications without Biome guidance unless the project enables Biome rules.

Applied to files:

  • apps/meteor/server/lib/parseMessageSearchQuery.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In this repository (RocketChat/Rocket.Chat), Biome lint rules are not used even if a biome.json exists. When reviewing TypeScript files (e.g., packages/ui-voip/src/providers/useMediaSession.ts), ensure lint suggestions do not reference Biome-specific rules. Rely on general ESLint/TypeScript lint rules and project conventions instead.

Applied to files:

  • apps/meteor/server/lib/parseMessageSearchQuery.ts
🔇 Additional comments (3)
apps/meteor/server/lib/parseMessageSearchQuery.ts (3)

47-52: Regex escaping and anchoring correctly fixes the search filter issue.

The use of escapeRegExp combined with ^...$ anchors properly ensures exact username matching, preventing regex metacharacters like . from acting as wildcards.


106-146: Good addition of escapeRegExp to label and file filters.

Applying escapeRegExp to consumeLabel, consumeFileDescription, and consumeFileTitle provides consistent handling of user input containing regex metacharacters across all filter types.


218-240: LGTM!

The arrow function wrappers cleanly maintain this context and improve readability.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Message search from: and mention: filters match unintended usernames when username contains a dot

1 participant