Skip to content

feat(webchat): add branding, avatars, and widget CSS hardening - #938

Merged
realcodesiman merged 2 commits into
mainfrom
feat/webchat-branding-security
Aug 11, 2026
Merged

feat(webchat): add branding, avatars, and widget CSS hardening#938
realcodesiman merged 2 commits into
mainfrom
feat/webchat-branding-security

Conversation

@realcodesiman

Copy link
Copy Markdown
Contributor

Summary

  • Auto-contrast the widget's foreground text against the admin-chosen brandColor instead of a hardcoded white, and show the workspace logo beside bot/agent bubbles (gated server-side on showLogo).
  • Sanitize IntegrationWebchat.customCss against </style> injection before it's rendered via dangerouslySetInnerHTML, and cap its length at 20k characters.
  • Close a privilege gap: updateWebchatAction only checked workspace membership, so any member (not just superAdmin, as the edit page requires) could set customCss served to the public widget — now gated on superAdmin via a new workspaceMemberPermissions field on the action ctx.
  • Small unrelated fixes bundled from the same working session: reload instead of toast+router.refresh() after workspace deletion actions, an account-rail plan label/layout tweak, and an add-channel-button anchor-instead-of-button fix.

Changes

  • apps/builder/src/features/integration-webchat/lib/brand-color.ts (new) — WCAG relative luminance + readable foreground helpers
  • apps/builder/src/features/integration-webchat/lib/widget-css.tsx (new) — sanitizeWidgetCss + CustomWidgetStyle server component
  • apps/builder/src/features/integration-webchat/actions/update-webchat.action.ts, apps/builder/src/lib/safe-action.ts — superAdmin permission gate on the action, workspaceMemberPermissions exposed on ctx
  • apps/builder/src/features/integration-webchat/schema/mutation.tscustomCss max length
  • apps/builder/src/app/(no-sidebar)/webchat/page.tsx, webchat-wrapper.tsx, webchat-message-list.tsx, guest-session-provider.tsx, guest-sesssion-store.ts — wire brand color + workspace logo through to the guest widget
  • apps/builder/src/features/messages/components/message-item.tsx — optional avatarUrl prop for agent/bot bubbles
  • apps/builder/src/features/integration-webchat/dialogs/embed-code-dialog.tsx, components/authorized-domain-field.tsx — trim unused embed snippet options, add domain field placeholder
  • apps/builder/src/features/workspaces/components/{account-rail,workspace-deletion-card}.tsx, apps/builder/src/features/inboxes/components/add-channel-button.tsx — unrelated small fixes
  • Translation keys added across all apps/builder/messages/*.json locales
  • New/updated tests under apps/builder/__tests__/ and apps/builder/src/features/workspaces/components/__tests__/

Test plan

  • pnpm lint
  • pnpm --filter builder check-types (required fixing an unrelated stale workspace link for @chatbotx.io/integration-instagram-facebook via CI=true pnpm install --no-frozen-lockfile)
  • Manual verification: load a webchat widget with a light brandColor and confirm header/button text stays readable; toggle showLogo and confirm the avatar appears/disappears; attempt updateWebchatAction as a non-superAdmin member and confirm it's rejected

- Auto-contrast foreground text against admin-chosen brandColor
  (getRelativeLuminance/readableForeground) instead of hardcoded white
- Show workspace logo beside bot/agent bubbles in the guest widget,
  gated server-side on showLogo
- Sanitize IntegrationWebchat.customCss against </style> injection
  before rendering via dangerouslySetInnerHTML; cap length at 20k
- Require superAdmin permission in updateWebchatAction, not just
  workspace membership, since it can set customCss served to the
  public widget; expose workspaceMemberPermissions on action ctx
- Trim embed snippet to only still-used options
- Reload instead of toast+refresh after workspace deletion actions;
  minor account-rail plan label and add-channel-button anchor fixes
- Add subtle border to ahc-iframe-container to highlight the chat bubble
- Increase message avatar size and adjust alignment
- Increase crown icon size in upgrade plan button
@realcodesiman
realcodesiman merged commit c37b6ad into main Aug 11, 2026
8 checks passed
@realcodesiman
realcodesiman deleted the feat/webchat-branding-security branch August 11, 2026 09:07
viethung0o0 pushed a commit that referenced this pull request Sep 7, 2026
* feat(webchat): add branding, avatars, and widget CSS hardening

- Auto-contrast foreground text against admin-chosen brandColor
  (getRelativeLuminance/readableForeground) instead of hardcoded white
- Show workspace logo beside bot/agent bubbles in the guest widget,
  gated server-side on showLogo
- Sanitize IntegrationWebchat.customCss against </style> injection
  before rendering via dangerouslySetInnerHTML; cap length at 20k
- Require superAdmin permission in updateWebchatAction, not just
  workspace membership, since it can set customCss served to the
  public widget; expose workspaceMemberPermissions on action ctx
- Trim embed snippet to only still-used options
- Reload instead of toast+refresh after workspace deletion actions;
  minor account-rail plan label and add-channel-button anchor fixes

* fix(builder): polish webchat iframe border and icon sizing

- Add subtle border to ahc-iframe-container to highlight the chat bubble
- Increase message avatar size and adjust alignment
- Increase crown icon size in upgrade plan button
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant