Skip to content

Conversation

@MrKalyanKing
Copy link

@MrKalyanKing MrKalyanKing commented Nov 9, 2025

[x] I have signed the CLA - https://cla-assistant.io/RocketChat/Rocket.Chat

[x] Lint and unit tests pass locally with my changes

[x] I have tested my fix locally and it is effective

[ ] I have added tests that prove my fix is effective or that my feature works (if applicable)

[ ] I have added necessary documentation (if applicable)

[ ] Any dependent changes have been merged and published in downstream modules

This PR fixes a bug in the Incoming Webhook form where the "Emoji" field was not being validated.

Previously, the form would accept any invalid string (e.g., "myemoji" or "ibjkn"), even though the help text implies a colon-wrapped format (e.g., 👻). This would save the integration but result in a broken avatar icon for all messages posted by the webhook.

This fix adds client-side validation using the react-hook-form validate prop. The logic checks if the input is either a single, valid emoji character OR if it follows the :emoji_name: format.

If the validation fails, it now triggers the validateEmoji error to show the error notification under the emoji filed (e.g., "Invalid emoji format"), preventing the form from being saved in a broken state.

Issue(s)

Closes #37451

Steps to test or reproduce

Navigate to Administration > Integrations.

Click the "New" button in the top-right corner.

Select the "Incoming" tab.

Fill in the required fields (e.g., Name: Test Emoji, Post to Channel: #general, Post as: kalyan12).

Scroll down to the "Emoji" field.

Type an invalid string that is not an emoji (e.g., ibjkn).

Click the "Save" button.

Before this fix: The form would save successfully.
After this fix: A red pop-up error toast appears (e.g., "Invalid emoji format"), and the form does not save.

Further comments

This bug appears to be part of a larger pattern of missing validation on the integration forms, similar to the URLs field bug (#37411) and the Avatar URL bug (#37423).

This fix follows the same pattern as the others:

The validateEmoji logic is added to the parent component (EditIncomingWebhookPage.tsx).

The handleInvalid function in the parent is used to trigger the error toast.

The rules prop is added to the in the child component (IncomingWebhookForm.tsx).

Summary by CodeRabbit

  • Bug Fixes

    • Added validation for Incoming Webhook Avatar URLs to ensure proper format and protocol
    • Added validation for emoji input in Incoming webhook forms
    • Enhanced error messaging and accessibility for integration webhook field validation
  • Chores

    • Added release note entries documenting the fixes for integration webhooks

@MrKalyanKing MrKalyanKing requested a review from a team as a code owner November 9, 2025 12:36
@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Nov 9, 2025

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 Nov 9, 2025

🦋 Changeset detected

Latest commit: cc0a775

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 41 packages
Name Type
@rocket.chat/meteor Major
@rocket.chat/core-typings Major
@rocket.chat/rest-typings Major
@rocket.chat/uikit-playground Patch
@rocket.chat/api-client Patch
@rocket.chat/apps Patch
@rocket.chat/core-services Patch
@rocket.chat/cron Patch
@rocket.chat/ddp-client Patch
@rocket.chat/freeswitch Patch
@rocket.chat/fuselage-ui-kit Major
@rocket.chat/gazzodown Major
@rocket.chat/http-router Patch
@rocket.chat/livechat Patch
@rocket.chat/model-typings Patch
@rocket.chat/ui-avatar Major
@rocket.chat/ui-client Major
@rocket.chat/ui-contexts Major
@rocket.chat/web-ui-registration Major
@rocket.chat/account-service Patch
@rocket.chat/authorization-service Patch
@rocket.chat/ddp-streamer Patch
@rocket.chat/omnichannel-transcript Patch
@rocket.chat/presence-service Patch
@rocket.chat/queue-worker Patch
@rocket.chat/stream-hub-service Patch
@rocket.chat/federation-matrix Patch
@rocket.chat/license Patch
@rocket.chat/media-calls Patch
@rocket.chat/omnichannel-services Patch
@rocket.chat/pdf-worker Patch
@rocket.chat/presence Patch
rocketchat-services Patch
@rocket.chat/models Patch
@rocket.chat/network-broker Patch
@rocket.chat/omni-core-ee Patch
@rocket.chat/mock-providers Patch
@rocket.chat/ui-video-conf Major
@rocket.chat/ui-voip Major
@rocket.chat/instance-status Patch
@rocket.chat/omni-core Patch

Not sure what this means? Click here to learn what changesets are.

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 9, 2025

Walkthrough

Adds client-side validation for Incoming Webhook Avatar URL and Emoji fields; updates form error UI/ARIA. Includes three changeset release notes and minor formatting/type helper edits in related webhook editor files.

Changes

Cohort / File(s) Summary
Release notes / Changesets
.changeset/funny-islands-run.md, .changeset/light-singers-join.md, .changeset/mighty-queens-hug.md
Adds three changeset entries for @rocket.chat/meteor documenting fixes: avatar validation and emoji validation for incoming webhooks (patch/major version notes). No code behavior changes.
Incoming Webhook Form
apps/meteor/client/views/admin/integrations/incoming/IncomingWebhookForm.tsx
Adds validateAvatarUrl and validateEmoji validators; integrates them into react-hook-form rules for Avatar_URL and Emoji; renders field-specific FieldError components; sets aria-describedby and aria-invalid for accessibility.
Incoming Webhook Editor (formatting)
apps/meteor/client/views/admin/integrations/incoming/EditIncomingWebhook.tsx
Whitespace/formatting adjustments only; no functional changes.
Outgoing Webhook Editor (small helpers/formatting)
apps/meteor/client/views/admin/integrations/outgoing/EditOutgoingWebhook.tsx
Adds internal type EditOutgoingWebhookFormData, getInitialValue helper and minor formatting; no public API changes.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Form as IncomingWebhookForm
    participant Validators as Validator functions
    participant UI as Field UI

    User->>Form: Populate Avatar_URL
    Form->>Validators: validateAvatarUrl(value)
    alt valid http/https URL
        Validators-->>Form: no error
        Form->>UI: ensure no error shown
    else invalid URL
        Validators-->>Form: error message
        Form->>UI: show FieldError, set aria-invalid
    end

    User->>Form: Populate Emoji
    Form->>Validators: validateEmoji(value)
    alt valid (:name:) or single pictograph or empty
        Validators-->>Form: no error
        Form->>UI: ensure no error shown
    else invalid format
        Validators-->>Form: error message
        Form->>UI: show FieldError, set aria-invalid
    end

    User->>Form: Submit
    alt all validations pass
        Form-->>User: proceed to save
    else validation fails
        Form-->>User: prevent save, display errors
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Review validator regex/logic for URL scheme and emoji format.
  • Confirm integration with react-hook-form rules and correct ARIA id wiring.
  • Verify translated error messages and FieldError rendering.
  • Quick sanity-check of changeset metadata and version tags.

Suggested labels

stat: ready to merge, stat: QA assured

Suggested reviewers

  • scuciatto
  • gabriellsh

Poem

🐇 I hop through fields with careful cheer,

Colons guard each emoji dear,
Avatars must start with http or https true,
Errors shown clearly — no broken view,
A tiny rabbit's nod to a webhook made new.

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Out of Scope Changes check ❓ Inconclusive The PR includes some formatting changes in EditIncomingWebhook.tsx and EditOutgoingWebhook.tsx that appear tangential to the emoji validation objective. Clarify whether whitespace and formatting changes in EditOutgoingWebhook.tsx are necessary or should be removed to keep the PR focused on emoji validation.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately describes the main change: adding validation to the Incoming webhook 'Emoji' field.
Linked Issues check ✅ Passed The PR implements emoji validation for the Incoming Webhook form by adding validateEmoji logic, error handling, and ARIA attributes as required by issue #37451.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@MrKalyanKing MrKalyanKing changed the title Fix/37451 emoji validation fix(integrations): Incoming webhook 'Emoji' field has no validation Nov 9, 2025
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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 20490af and 7ad4f5c.

📒 Files selected for processing (6)
  • .changeset/funny-islands-run.md (1 hunks)
  • .changeset/light-singers-join.md (1 hunks)
  • .changeset/mighty-queens-hug.md (1 hunks)
  • apps/meteor/client/views/admin/integrations/incoming/EditIncomingWebhook.tsx (3 hunks)
  • apps/meteor/client/views/admin/integrations/incoming/IncomingWebhookForm.tsx (2 hunks)
  • apps/meteor/client/views/admin/integrations/outgoing/EditOutgoingWebhook.tsx (4 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 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
🪛 ast-grep (0.39.7)
apps/meteor/client/views/admin/integrations/incoming/IncomingWebhookForm.tsx

[warning] 318-318: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html

(react-unsafe-html-injection)

🪛 Biome (2.1.2)
apps/meteor/client/views/admin/integrations/incoming/IncomingWebhookForm.tsx

[error] 319-319: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

'@rocket.chat/meteor': major
---

fix(integrations): Add validation for Incoming Webhook Avatar
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

Changelog entry should reflect the primary fix (emoji validation) and mention both validations added.

The changeset message only mentions "Avatar" validation, but according to the PR objectives and the linked issue #37451, the primary fix is for emoji field validation. The AI summary context also indicates that both validateAvatarUrl and validateEmoji validators are being added. The changelog entry should be more accurate and complete.

Consider updating the changelog message to clarify the primary objective and mention both validations:

- fix(integrations): Add validation for Incoming Webhook Avatar
+ fix(integrations): Add validation for Incoming Webhook Emoji and Avatar URL

Alternatively, if emoji validation is the primary fix:

- fix(integrations): Add validation for Incoming Webhook Avatar
+ fix(integrations): Add validation for Incoming Webhook Emoji field format
📝 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
fix(integrations): Add validation for Incoming Webhook Avatar
fix(integrations): Add validation for Incoming Webhook Emoji and Avatar URL
🤖 Prompt for AI Agents
In .changeset/funny-islands-run.md around line 5, the changelog line only
mentions "Avatar" validation but the PR primarily fixes emoji field validation
and adds both validateAvatarUrl and validateEmoji; update the changelog entry to
clearly state the primary fix (emoji validation) and also mention that avatar
URL validation was added so both validations are reflected in the message.

Comment on lines 48 to 56
const validateEmoji = (value: string) => {
if (!value) return true;

if (/^:.+:$/.test(value)) {
return true;
}

return t('Invalid_emoji_format_Must_be_in_colon_format', { example: ':ghost:' });
};
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

Allow actual emoji glyphs as well

The new validator only accepts :name: patterns, but the issue description and help text say the field should also allow a single real emoji (e.g. 🙂). With the current regex that input is rejected, so users still get blocked. Please extend the validator (and error copy) so both formats pass—for example by accepting ^:.+:$ or a single Extended_Pictographic code point:

-	if (/^:.+:$/.test(value)) {
-		return true;
-	}
-
-	return t('Invalid_emoji_format_Must_be_in_colon_format', { example: ':ghost:' });
+	if (/^:.+:$/.test(value)) {
+		return true;
+	}
+
+	if ([...value.trim()].length === 1 && /\p{Extended_Pictographic}/u.test(value)) {
+		return true;
+	}
+
+	return t('Invalid_emoji_format_Must_be_in_colon_format', { example: ':ghost:' });

Please also update the error message so it mentions both accepted formats after adjusting the translation.

🤖 Prompt for AI Agents
In apps/meteor/client/views/admin/integrations/incoming/IncomingWebhookForm.tsx
around lines 48 to 56, the validator currently only accepts colon-wrapped
shortcode patterns and rejects actual emoji glyphs; update the validation to
accept either a :name: pattern OR a single Extended_Pictographic emoji (e.g. use
a regex like /^:.+:$|^\p{Extended_Pictographic}$/u or equivalent unicode-aware
check) while keeping empty values valid, and change the error
message/translation key used to mention both accepted formats (colon shortcodes
and single emoji glyph) so the UI reflects the new validation.

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: 0

🧹 Nitpick comments (1)
apps/meteor/client/views/admin/integrations/incoming/IncomingWebhookForm.tsx (1)

48-60: Fix indentation inconsistency.

The validation logic correctly handles both colon-wrapped emoji (:ghost:) and actual emoji glyphs as required. However, lines 52-53 have inconsistent indentation.

Apply this diff to fix the indentation:

 	const validateEmoji = (value: string) => {
 		if (!value) return true;
 
 		if (/^:.+:$/.test(value)) {
-		return true;
-	}
+			return true;
+		}
 
 	if ([...value.trim()].length === 1 && /\p{Extended_Pictographic}/u.test(value)) {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 7ad4f5c and cc0a775.

📒 Files selected for processing (3)
  • .changeset/mighty-queens-hug.md (1 hunks)
  • apps/meteor/client/views/admin/integrations/incoming/IncomingWebhookForm.tsx (2 hunks)
  • apps/meteor/client/views/admin/integrations/outgoing/EditOutgoingWebhook.tsx (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/meteor/client/views/admin/integrations/outgoing/EditOutgoingWebhook.tsx
  • .changeset/mighty-queens-hug.md
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
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.
📚 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
🪛 ast-grep (0.39.7)
apps/meteor/client/views/admin/integrations/incoming/IncomingWebhookForm.tsx

[warning] 322-322: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html

(react-unsafe-html-injection)

🪛 Biome (2.1.2)
apps/meteor/client/views/admin/integrations/incoming/IncomingWebhookForm.tsx

[error] 323-323: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

🔇 Additional comments (3)
apps/meteor/client/views/admin/integrations/incoming/IncomingWebhookForm.tsx (3)

35-46: LGTM! Clean URL validation.

The validation logic correctly handles HTTP/HTTPS URLs, allows empty values, and returns translated error messages for invalid input.


267-293: LGTM! Proper validation and ARIA implementation.

The avatar field validation follows the same pattern as the channel and username fields in this file. The ARIA attributes are correctly configured with matching error ids, and the FieldError is properly positioned.


295-325: LGTM! Consistent validation implementation.

The emoji field validation correctly mirrors the avatar field pattern with proper ARIA attributes and error handling. The static analysis warnings about dangerouslySetInnerHTML on line 323 are false positives—the content is sanitized using DOMPurify.sanitize, which is the correct approach and consistent with other usages in this file (lines 142, 210).

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.

fix(Integration): Incoming webhook 'Emoji filed 'has no validation

2 participants