Skip to content

Comments

fix: enforce validation for Incoming WebHook alias field (#38849)#38909

Open
TechByAnshuu wants to merge 2 commits intoRocketChat:developfrom
TechByAnshuu:Fix--Validate-Incoming-WebHook-Alias-field-(#38849)
Open

fix: enforce validation for Incoming WebHook alias field (#38849)#38909
TechByAnshuu wants to merge 2 commits intoRocketChat:developfrom
TechByAnshuu:Fix--Validate-Incoming-WebHook-Alias-field-(#38849)

Conversation

@TechByAnshuu
Copy link

@TechByAnshuu TechByAnshuu commented Feb 22, 2026

Description

Problem

The Alias field in Incoming WebHook integrations had no validation of any kind. Aliases of unlimited length or containing arbitrary special characters were silently accepted and rendered as the message sender name in chat — causing UI overflow, inconsistent behavior with other validated webhook fields, and no rejection even when calling the REST API directly, bypassing the UI entirely.

Solution

This PR introduces dual-layer validation — enforced independently at both the client and server — with a Unicode-aware character pattern so the fix works correctly for all Rocket.Chat workspaces globally, not just English ones.

This is my contribution as part of my GSoC 2025 application to Rocket.Chat. I reviewed the existing validation patterns used by other webhook fields, identified the missing constraint on alias, and implemented a solution that is consistent with the codebase architecture — using shared constants, REST schema enforcement via Ajv, and react-hook-form on the client.


Changes

⚙️ Server

  • Created packages/core-typings/src/integrations/constants.ts — centralized single source of truth exporting:
    • ALIAS_MAX_LENGTH50
    • ALIAS_ALLOWED_PATTERN/^[\p{L}\p{N} _-]*$/u
    • ALIAS_ALLOWED_PATTERN_DESCRIPTION → human-readable error string
  • Updated packages/core-typings/tsconfig.json to target es2020 — required for TypeScript to compile Unicode property escapes without errors
  • Exported constants through packages/core-typings/src/index.ts for cross-package consumption
  • Added maxLength and pattern constraints to alias in both:
    • IntegrationsCreateProps.ts
    • IntegrationsUpdateProps.ts
    Both endpoints are protected — a developer calling the API directly via curl or Postman is rejected before any database write occurs

🎨 Client

  • Integrated react-hook-form validation on the alias input in IncomingWebhookForm.tsx
  • Live character counter 12/50 shown as input addon — user is guided before hitting Save
  • Inline FieldError displayed instantly on invalid input
  • HTML maxLength attribute set as browser-level hard cap
  • Save button remains disabled while validation errors are active

🧪 Tests

7 end-to-end test cases added to incoming-integrations.ts:

# | Input | Expected | What it proves -- | -- | -- | -- 1 | 51-character string | 400 | Limit is ≤ 50 not < 50 2 | @#$$Invalid! | 400 | Character whitelist enforced 3 | 50-character string | 200 | Boundary is inclusive 4 | My-Bot_v2 | 200 | Standard valid case works 5 | Hürriyet_日本語_عربى | 200 | Unicode pattern is real 6 | No alias field | 200 | Field remains optional 7 | Empty string "" | 200 | Backward compatibility held

Issue

Closes #38849


Verification Steps

Reproduce the original bug (on develop without this PR):

  1. Go to Administration → Workspace → Integrations → New Integration → Incoming WebHook
  2. Enter 100+ characters in the Alias field and save — accepted with no error
  3. Enter @#$$ in the Alias field and save — accepted with no error

Verify the fix (on this branch):

  1. Go to Administration → Workspace → Integrations → New Integration → Incoming WebHook
  2. Type 51+ characters in Alias — counter shows 51/50, inline error appears, Save is disabled
  3. Clear, type @#$$ — inline error appears instantly
  4. Clear, type My-Bot_v2 — no error, Save enabled, webhook posts correctly
  5. Clear, type Hürriyet_日本語 — accepted, no error (Unicode support confirmed)
  6. Leave Alias empty — webhook saves and triggers correctly (optional field preserved)

Run tests:

bash
cd apps/meteor
yarn test:e2e --grep "Incoming WebHook Alias"

Design Decisions

Why Unicode pattern instead of a-zA-Z0-9? Rocket.Chat is a global product. An ASCII-only pattern silently rejects valid bot names in Arabic, Japanese, German, and Hindi workspaces with no explanation to the user. /^[\p{L}\p{N} _-]*$/u handles all Unicode scripts correctly with a single pattern and zero special cases.

Why dual-layer validation? Client validation is UX. Server validation is security. A developer calling the REST API directly bypasses the React form entirely — Ajv schema enforcement is the only layer that protects the database in that path.

Why 50 characters? The alias renders as the sender name above every webhook message. 50 characters fits within Rocket.Chat's message UI on the smallest commonly supported viewport without overflow or truncation.

Why es2020 in tsconfig? Unicode property escapes require ES2018+ to compile. The previous target caused TypeScript to error on the /u flag. es2020 aligns with what the broader Rocket.Chat codebase already targets and introduces no breaking changes.

Summary by CodeRabbit

  • New Features
    • Added validation for webhook integration aliases with 50-character maximum and real-time character counter display
    • Error messages show inline when aliases contain invalid characters (only alphanumeric, spaces, underscores, and hyphens allowed)
    • Improved field accessibility with ARIA attributes for validation feedback
    • New optional runOnEdits configuration option for outgoing webhook integrations

…at#38849)

Problem: The Alias field in Incoming WebHook integrations accepted any input without validation — unlimited length and arbitrary special characters were silently saved and rendered in chat messages, causing UI breakage and inconsistent behavior with other webhook fields.

Solution: - Add shared constants (ALIAS_MAX_LENGTH: 50, ALIAS_ALLOWED_PATTERN: Unicode /^[\p{L}\p{N} _-]*$/u) to packages/core-typings as a single source of truth for both client and server - Update packages/core-typings/tsconfig.json to target es2020 to support Unicode property escape compilation - Enforce maxLength and pattern constraints in IntegrationsCreateProps.ts and IntegrationsUpdateProps.ts REST schemas via Ajv — rejects malformed aliases at API level before any DB write - Integrate react-hook-form validation in IncomingWebhookForm.tsx with live character counter (12/50) and inline FieldError - Set HTML maxLength as browser-level hard cap - Add 7 end-to-end test cases covering: over-limit length, invalid characters, boundary (50 chars), valid alias, Unicode alias (Hürriyet_日本語_عربى), omitted alias, and empty string alias. Closes RocketChat#38849

Co-authored-by: roushnisareen <roushnisareen@gmail.com>
@TechByAnshuu TechByAnshuu requested review from a team as code owners February 22, 2026 18:14
@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Feb 22, 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

@changeset-bot
Copy link

changeset-bot bot commented Feb 22, 2026

⚠️ No Changeset found

Latest commit: 8b30e48

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.

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

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 22, 2026

Walkthrough

This PR implements validation for the incoming webhook alias field, enforcing a maximum length of 50 characters and restricting characters to alphanumeric, underscore, hyphen, and Unicode characters. Changes span UI form validation, API schemas, shared constants, and end-to-end tests.

Changes

Cohort / File(s) Summary
Alias validation constants
packages/core-typings/src/integrations/constants.ts, packages/core-typings/src/index.ts
Introduces ALIAS_MAX_LENGTH (50), ALIAS_ALLOWED_PATTERN (Unicode-aware regex), and ALIAS_ALLOWED_PATTERN_DESCRIPTION; re-exports from core-typings index.
Frontend alias field validation
apps/meteor/client/views/admin/integrations/incoming/IncomingWebhookForm.tsx
Enhances alias TextInput with maxLength validation, ARIA attributes, real-time error display, and character count indicator showing current length / max length.
API schema validation
packages/rest-typings/src/v1/integrations/IntegrationsCreateProps.ts, packages/rest-typings/src/v1/integrations/IntegrationsUpdateProps.ts
Applies maxLength and pattern constraints to alias field in webhook-incoming and webhook-outgoing schemas; IntegrationsUpdateProps adds optional runOnEdits field to webhook-outgoing branch.
TypeScript configuration
packages/core-typings/tsconfig.json
Updates compiler target to es2020, expands lib to include dom, dom.iterable, and es2020; restructures plugins and include configurations.
End-to-end test suite
apps/meteor/tests/end-to-end/api/incoming-integrations.ts
Adds comprehensive alias validation tests covering oversized aliases, special characters, max-length acceptance, Unicode support, and scenarios with missing or empty alias values.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A webhook's alias now stands tall and true,
With fifty chars max—no more than is due,
No special symbols shall pass through our gate,
Just letters and numbers, pristine and first-rate! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 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: enforcing validation for the Incoming WebHook alias field, which aligns with the core objective of adding validation constraints.
Linked Issues check ✅ Passed The PR successfully implements all coding requirements from issue #38849: dual-layer validation (client and server), character pattern constraints, length limits, and comprehensive end-to-end tests. The other linked issues (MB-1, MB-3) are unrelated to this code change.
Out of Scope Changes check ✅ Passed The tsconfig.json changes to es2020 target/lib and plugin restructuring are required dependencies for the validation constants' Unicode regex support, making them in-scope. All other changes directly support alias validation objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ 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
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 7 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/core-typings/src/integrations/constants.ts">

<violation number="1" location="packages/core-typings/src/integrations/constants.ts:3">
P2: Alias validation regex excludes Unicode combining marks (\p{M}), which will reject valid aliases for scripts that require combining marks (e.g., Hindi/Devanagari, Thai, fully vocalized Arabic).</violation>
</file>

Since this is your first cubic review, here's how it works:

  • cubic automatically reviews your code and comments on bugs and improvements
  • Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
  • Add one-off context when rerunning by tagging @cubic-dev-ai with guidance or docs links (including llms.txt)
  • Ask questions if you need clarification on any suggestion

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

@@ -0,0 +1,6 @@
export const ALIAS_MAX_LENGTH = 50;

export const ALIAS_ALLOWED_PATTERN = /^[\p{L}\p{N} _-]*$/u;
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Feb 22, 2026

Choose a reason for hiding this comment

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

P2: Alias validation regex excludes Unicode combining marks (\p{M}), which will reject valid aliases for scripts that require combining marks (e.g., Hindi/Devanagari, Thai, fully vocalized Arabic).

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/core-typings/src/integrations/constants.ts, line 3:

<comment>Alias validation regex excludes Unicode combining marks (\p{M}), which will reject valid aliases for scripts that require combining marks (e.g., Hindi/Devanagari, Thai, fully vocalized Arabic).</comment>

<file context>
@@ -0,0 +1,6 @@
+export const ALIAS_MAX_LENGTH = 50;
+
+export const ALIAS_ALLOWED_PATTERN = /^[\p{L}\p{N} _-]*$/u;
+
+export const ALIAS_ALLOWED_PATTERN_DESCRIPTION =
</file context>
Fix with Cubic

@TechByAnshuu
Copy link
Author

Hi @rocketchat-cloudbot

This is my first contribution to Rocket.Chat. I have gone through the
Contributing Guide, signed the CLA, and made sure lint and tests pass locally.

Happy to make any changes based on your feedback — whether that is adjusting
the character limit, the allowed pattern, or the validation approach. I am
also open to splitting this into smaller commits if that is preferred.

Looking forward to your review.

Copy link
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: 3

🧹 Nitpick comments (1)
apps/meteor/tests/end-to-end/api/incoming-integrations.ts (1)

177-177: Import and use ALIAS_MAX_LENGTH instead of hardcoded 51/50.

If ALIAS_MAX_LENGTH ever changes, these tests will silently test the wrong boundary. Importing the constant keeps the tests automatically in sync with the validation rule.

♻️ Proposed fix

At the top of the file, add:

+ import { ALIAS_MAX_LENGTH } from '@rocket.chat/core-typings';

Then in the test bodies:

-   alias: 'a'.repeat(51),
+   alias: 'a'.repeat(ALIAS_MAX_LENGTH + 1),
-   alias: 'a'.repeat(50),
+   alias: 'a'.repeat(ALIAS_MAX_LENGTH),

Also applies to: 215-215

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/tests/end-to-end/api/incoming-integrations.ts` at line 177,
Import the validation constant ALIAS_MAX_LENGTH at the top of the test file and
replace hardcoded usages like alias: 'a'.repeat(51) (and the other occurrence at
the later test) with dynamic expressions using that constant: use alias:
'a'.repeat(ALIAS_MAX_LENGTH + 1) for the "too long" case and alias:
'a'.repeat(ALIAS_MAX_LENGTH) for the boundary/valid case so tests remain correct
if ALIAS_MAX_LENGTH changes; update the two alias properties in the test bodies
accordingly.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3145c41 and 8b30e48.

📒 Files selected for processing (7)
  • apps/meteor/client/views/admin/integrations/incoming/IncomingWebhookForm.tsx
  • apps/meteor/tests/end-to-end/api/incoming-integrations.ts
  • packages/core-typings/src/index.ts
  • packages/core-typings/src/integrations/constants.ts
  • packages/core-typings/tsconfig.json
  • packages/rest-typings/src/v1/integrations/IntegrationsCreateProps.ts
  • packages/rest-typings/src/v1/integrations/IntegrationsUpdateProps.ts
🧰 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:

  • packages/core-typings/src/index.ts
  • packages/core-typings/src/integrations/constants.ts
  • apps/meteor/client/views/admin/integrations/incoming/IncomingWebhookForm.tsx
  • packages/rest-typings/src/v1/integrations/IntegrationsUpdateProps.ts
  • apps/meteor/tests/end-to-end/api/incoming-integrations.ts
  • packages/rest-typings/src/v1/integrations/IntegrationsCreateProps.ts
🧠 Learnings (8)
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to **/*.{ts,tsx,js} : Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests

Applied to files:

  • packages/core-typings/tsconfig.json
📚 Learning: 2025-12-10T21:00:54.909Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37091
File: ee/packages/abac/jest.config.ts:4-7
Timestamp: 2025-12-10T21:00:54.909Z
Learning: Rocket.Chat monorepo: Jest testMatch pattern '<rootDir>/src/**/*.spec.(ts|js|mjs)' is valid in this repo and used across multiple packages (e.g., packages/tools, ee/packages/omnichannel-services). Do not flag it as invalid in future reviews.

Applied to files:

  • packages/core-typings/tsconfig.json
  • apps/meteor/tests/end-to-end/api/incoming-integrations.ts
📚 Learning: 2025-09-18T17:32:33.969Z
Learnt from: aleksandernsilva
Repo: RocketChat/Rocket.Chat PR: 36974
File: apps/meteor/client/components/Omnichannel/OutboundMessage/components/OutboundMessageWizard/forms/MessageForm/MessageForm.tsx:124-129
Timestamp: 2025-09-18T17:32:33.969Z
Learning: The ARIA mismatch issue in MessageForm's template field (where FieldError id used templateId instead of messageFormId) was addressed in PR `#36972` through refactoring the template field into a separate TemplateField component, which uses consistent templateFieldId for both aria-describedby and FieldError id.

Applied to files:

  • apps/meteor/client/views/admin/integrations/incoming/IncomingWebhookForm.tsx
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : All test files must be created in `apps/meteor/tests/e2e/` directory

Applied to files:

  • apps/meteor/tests/end-to-end/api/incoming-integrations.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Ensure tests run reliably in parallel without shared state conflicts

Applied to files:

  • apps/meteor/tests/end-to-end/api/incoming-integrations.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Group related tests in the same file

Applied to files:

  • apps/meteor/tests/end-to-end/api/incoming-integrations.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Utilize Playwright fixtures (`test`, `page`, `expect`) for consistency in test files

Applied to files:

  • apps/meteor/tests/end-to-end/api/incoming-integrations.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use `expect` matchers for assertions (`toEqual`, `toContain`, `toBeTruthy`, `toHaveLength`, etc.) instead of `assert` statements in Playwright tests

Applied to files:

  • apps/meteor/tests/end-to-end/api/incoming-integrations.ts
🧬 Code graph analysis (4)
apps/meteor/client/views/admin/integrations/incoming/IncomingWebhookForm.tsx (1)
packages/core-typings/src/integrations/constants.ts (3)
  • ALIAS_MAX_LENGTH (1-1)
  • ALIAS_ALLOWED_PATTERN (3-3)
  • ALIAS_ALLOWED_PATTERN_DESCRIPTION (5-6)
packages/rest-typings/src/v1/integrations/IntegrationsUpdateProps.ts (1)
packages/core-typings/src/integrations/constants.ts (2)
  • ALIAS_MAX_LENGTH (1-1)
  • ALIAS_ALLOWED_PATTERN (3-3)
apps/meteor/tests/end-to-end/api/incoming-integrations.ts (2)
packages/core-services/src/index.ts (1)
  • api (55-55)
apps/meteor/app/integrations/server/lib/triggerHandler.ts (1)
  • removeIntegration (100-104)
packages/rest-typings/src/v1/integrations/IntegrationsCreateProps.ts (1)
packages/core-typings/src/integrations/constants.ts (2)
  • ALIAS_MAX_LENGTH (1-1)
  • ALIAS_ALLOWED_PATTERN (3-3)
🔇 Additional comments (3)
packages/core-typings/src/integrations/constants.ts (1)

1-6: LGTM!

Constants are cleanly defined. The u flag on ALIAS_ALLOWED_PATTERN correctly enables Unicode property escapes (\p{L}, \p{N}), and the * quantifier intentionally permits an empty alias.

packages/core-typings/src/index.ts (1)

26-26: LGTM!

Re-export is correctly positioned alongside other integration-related exports.

packages/rest-typings/src/v1/integrations/IntegrationsCreateProps.ts (1)

91-93: No action required. The codebase uses Ajv v8.17.1, which defaults to unicodeRegExp: true and automatically applies the u flag when compiling the pattern keyword. Unicode property escapes (\p{L}, \p{N}) in ALIAS_ALLOWED_PATTERN.source are processed correctly with no configuration needed.

Likely an incorrect or invalid review comment.

🤖 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/client/views/admin/integrations/incoming/IncomingWebhookForm.tsx`:
- Around line 238-241: The validation message ALIAS_ALLOWED_PATTERN_DESCRIPTION
is not localized; update the incoming webhook form to use the translation
function instead of the hardcoded constant: replace the direct use of
ALIAS_ALLOWED_PATTERN_DESCRIPTION in the pattern.message (inside the component
handling validation in IncomingWebhookForm, where pattern: { value:
ALIAS_ALLOWED_PATTERN, message: ALIAS_ALLOWED_PATTERN_DESCRIPTION }) with
t('Alias_allowed_characters') (or t('Alias_allowed_pattern_description')) and
add the matching key/value to the i18n JSON resources so the validator falls
back to the translated string.
- Around line 244-268: The TextInput for the alias field is passing an error
prop (error={errors?.alias?.message}) which duplicates the message already
rendered by the separate <FieldError> block; remove the redundant error prop
from the TextInput inside the Controller render (the JSX using TextInput with
id={aliasField} and {...field}) and keep only
aria-invalid={Boolean(errors?.alias)} plus the existing <FieldError> that
displays errors.alias.message so the alias validation message is shown once.

In `@packages/core-typings/tsconfig.json`:
- Around line 5-9: This tsconfig includes browser libs unnecessarily; remove
"dom" and "dom.iterable" from the "lib" array so only "es2020" remains, ensuring
server-side typings are used (it extends the server tsconfig) and the
ALIAS_ALLOWED_PATTERN regex that relies on Unicode property escapes (\p{L},
\p{N}) will still be supported by es2020; update the "lib" array entries in the
current tsconfig (remove the "dom" and "dom.iterable" strings) and run a quick
typecheck to confirm no browser globals (Window, Document, HTMLElement) are
exposed.

---

Duplicate comments:
In `@packages/rest-typings/src/v1/integrations/IntegrationsUpdateProps.ts`:
- Around line 97-99: The pattern is passing a RegExp.source
(ALIAS_ALLOWED_PATTERN.source) which can misbehave with Ajv's Unicode handling;
replace usage with a dedicated string pattern export (e.g., export const
ALIAS_ALLOWED_PATTERN_STRING = ALIAS_ALLOWED_PATTERN.toString().slice(1, -1) or
explicitly defined pattern string) and use that string in
IntegrationsUpdateProps (replace ALIAS_ALLOWED_PATTERN.source with
ALIAS_ALLOWED_PATTERN_STRING) for both pattern occurrences so Ajv receives a
proper string regex and Unicode behavior is deterministic.

---

Nitpick comments:
In `@apps/meteor/tests/end-to-end/api/incoming-integrations.ts`:
- Line 177: Import the validation constant ALIAS_MAX_LENGTH at the top of the
test file and replace hardcoded usages like alias: 'a'.repeat(51) (and the other
occurrence at the later test) with dynamic expressions using that constant: use
alias: 'a'.repeat(ALIAS_MAX_LENGTH + 1) for the "too long" case and alias:
'a'.repeat(ALIAS_MAX_LENGTH) for the boundary/valid case so tests remain correct
if ALIAS_MAX_LENGTH changes; update the two alias properties in the test bodies
accordingly.

Comment on lines +238 to +241
pattern: {
value: ALIAS_ALLOWED_PATTERN,
message: ALIAS_ALLOWED_PATTERN_DESCRIPTION,
},
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

ALIAS_ALLOWED_PATTERN_DESCRIPTION is not translated.

Every other validation error message in this form goes through t() (e.g., t('Max_length_is', ...), t('Required_field', ...)). ALIAS_ALLOWED_PATTERN_DESCRIPTION is a hardcoded English string and will not be localized for non-English users. Either add a translation key to the i18n resources and use t('Alias_allowed_pattern_description'), or pass the constant only as a fallback.

♻️ Proposed fix — use translation
  pattern: {
    value: ALIAS_ALLOWED_PATTERN,
-   message: ALIAS_ALLOWED_PATTERN_DESCRIPTION,
+   message: t('Alias_allowed_characters'),
  },

Then add the key to the relevant i18n JSON:

"Alias_allowed_characters": "Only letters, numbers, spaces, hyphens, and underscores are allowed"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/client/views/admin/integrations/incoming/IncomingWebhookForm.tsx`
around lines 238 - 241, The validation message ALIAS_ALLOWED_PATTERN_DESCRIPTION
is not localized; update the incoming webhook form to use the translation
function instead of the hardcoded constant: replace the direct use of
ALIAS_ALLOWED_PATTERN_DESCRIPTION in the pattern.message (inside the component
handling validation in IncomingWebhookForm, where pattern: { value:
ALIAS_ALLOWED_PATTERN, message: ALIAS_ALLOWED_PATTERN_DESCRIPTION }) with
t('Alias_allowed_characters') (or t('Alias_allowed_pattern_description')) and
add the matching key/value to the i18n JSON resources so the validator falls
back to the translated string.

Comment on lines +244 to +268
<TextInput
id={aliasField}
{...field}
maxLength={ALIAS_MAX_LENGTH}
aria-describedby={`${aliasField}-hint ${aliasField}-error`}
aria-invalid={Boolean(errors?.alias)}
error={errors?.alias?.message}
addon={
<>
<Box is='span' fontScale='micro' color='hint' mie='x8'>
{alias?.length ?? 0}/{ALIAS_MAX_LENGTH}
</Box>
<Icon name='edit' size='x20' />
</>
}
/>
)}
/>
</FieldRow>
<FieldHint id={`${aliasField}-hint`}>{t('Choose_the_alias_that_will_appear_before_the_username_in_messages')}</FieldHint>
{errors?.alias && (
<FieldError aria-live='assertive' id={`${aliasField}-error`}>
{errors.alias.message}
</FieldError>
)}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Redundant error prop causes double error rendering.

The error={errors?.alias?.message} prop on TextInput (line 250) renders the error message inside the input component. The <FieldError> block at lines 264–268 renders the same message again. Every other validated field in this component (channel, username) follows the correct pattern: only aria-invalid on TextInput plus a separate <FieldError>, with no error prop on the input itself.

🐛 Proposed fix — remove the redundant `error` prop
  <TextInput
    id={aliasField}
    {...field}
    maxLength={ALIAS_MAX_LENGTH}
    aria-describedby={`${aliasField}-hint ${aliasField}-error`}
    aria-invalid={Boolean(errors?.alias)}
-   error={errors?.alias?.message}
    addon={
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<TextInput
id={aliasField}
{...field}
maxLength={ALIAS_MAX_LENGTH}
aria-describedby={`${aliasField}-hint ${aliasField}-error`}
aria-invalid={Boolean(errors?.alias)}
error={errors?.alias?.message}
addon={
<>
<Box is='span' fontScale='micro' color='hint' mie='x8'>
{alias?.length ?? 0}/{ALIAS_MAX_LENGTH}
</Box>
<Icon name='edit' size='x20' />
</>
}
/>
)}
/>
</FieldRow>
<FieldHint id={`${aliasField}-hint`}>{t('Choose_the_alias_that_will_appear_before_the_username_in_messages')}</FieldHint>
{errors?.alias && (
<FieldError aria-live='assertive' id={`${aliasField}-error`}>
{errors.alias.message}
</FieldError>
)}
<TextInput
id={aliasField}
{...field}
maxLength={ALIAS_MAX_LENGTH}
aria-describedby={`${aliasField}-hint ${aliasField}-error`}
aria-invalid={Boolean(errors?.alias)}
addon={
<>
<Box is='span' fontScale='micro' color='hint' mie='x8'>
{alias?.length ?? 0}/{ALIAS_MAX_LENGTH}
</Box>
<Icon name='edit' size='x20' />
</>
}
/>
)}
</FieldRow>
<FieldHint id={`${aliasField}-hint`}>{t('Choose_the_alias_that_will_appear_before_the_username_in_messages')}</FieldHint>
{errors?.alias && (
<FieldError aria-live='assertive' id={`${aliasField}-error`}>
{errors.alias.message}
</FieldError>
)}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/client/views/admin/integrations/incoming/IncomingWebhookForm.tsx`
around lines 244 - 268, The TextInput for the alias field is passing an error
prop (error={errors?.alias?.message}) which duplicates the message already
rendered by the separate <FieldError> block; remove the redundant error prop
from the TextInput inside the Controller render (the JSX using TextInput with
id={aliasField} and {...field}) and keep only
aria-invalid={Boolean(errors?.alias)} plus the existing <FieldError> that
displays errors.alias.message so the alias validation message is shown once.

Comment on lines +5 to +9
"lib": [
"dom",
"dom.iterable",
"es2020"
],
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify whether any existing file in packages/core-typings/src references DOM-only types
rg -n "\b(HTMLElement|HTMLInputElement|Window|Document|EventTarget|MouseEvent|KeyboardEvent|CustomEvent)\b" packages/core-typings/src/

Repository: RocketChat/Rocket.Chat

Length of output: 269


🏁 Script executed:

cat -n packages/core-typings/tsconfig.json

Repository: RocketChat/Rocket.Chat

Length of output: 544


🏁 Script executed:

rg -n "ALIAS_ALLOWED_PATTERN" packages/core-typings/src/ -A 2 -B 2

Repository: RocketChat/Rocket.Chat

Length of output: 608


Remove dom and dom.iterable from the lib array.

packages/core-typings extends @rocket.chat/tsconfig/server.json, indicating server-side usage. The ALIAS_ALLOWED_PATTERN regex uses Unicode property escapes (\p{L}, \p{N}), which require only es2020—not DOM types. Adding dom and dom.iterable unnecessarily exposes browser-specific globals (Window, Document, HTMLElement, etc.) to server-side consumers, risking accidental browser API usage in server-only code.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core-typings/tsconfig.json` around lines 5 - 9, This tsconfig
includes browser libs unnecessarily; remove "dom" and "dom.iterable" from the
"lib" array so only "es2020" remains, ensuring server-side typings are used (it
extends the server tsconfig) and the ALIAS_ALLOWED_PATTERN regex that relies on
Unicode property escapes (\p{L}, \p{N}) will still be supported by es2020;
update the "lib" array entries in the current tsconfig (remove the "dom" and
"dom.iterable" strings) and run a quick typecheck to confirm no browser globals
(Window, Document, HTMLElement) are exposed.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG: Incoming WebHook Alias field accepts invalid values without validation

2 participants