Rocket.Chat icon indicating copy to clipboard operation
Rocket.Chat copied to clipboard

fix: router failing to match channel route when 'First Channel After Login' starts with a hash

Open abhinavkrin opened this issue 3 months ago • 5 comments

Proposed changes (including videos or screenshots)

This PR fixes an issue where the router failed to match the channel route when the “First Channel After Login” setting started with a hash (#).
Because URLs interpret # as the beginning of a fragment, the browser stops parsing the path at that point, causing the router to treat the channel name as invalid. As a result, the client loaded an not-found error page, and the sidebar did not appear.

This fix removes the leading hash before routing, ensuring the channel is resolved correctly, and the client loads normally after login.

Issue(s)

Steps to test or reproduce

Further comments

SUP-916

Summary by CodeRabbit

  • Bug Fixes

    • Fixed "First Channel After Login" redirect so channel names starting with "#" are normalized and users are routed correctly.
    • Redirect now triggers only for home routes and runs once per session to avoid repeated navigation.
  • Tests

    • Added comprehensive tests covering redirect behavior across home, root, non-home routes, empty setting, and re-renders.

✏️ Tip: You can customize this high-level summary in your review settings.

abhinavkrin avatar Dec 01 '25 17:12 abhinavkrin

Looks like this PR is ready to merge! 🎉 If you have any trouble, please check the PR guidelines

dionisio-bot[bot] avatar Dec 01 '25 17:12 dionisio-bot[bot]

🦋 Changeset detected

Latest commit: e29a17764fb8a1d0e26fb70a18ad894553315bf8

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 Patch
@rocket.chat/core-typings Patch
@rocket.chat/rest-typings Patch
@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 Patch
@rocket.chat/gazzodown Patch
@rocket.chat/http-router Patch
@rocket.chat/livechat Patch
@rocket.chat/model-typings Patch
@rocket.chat/ui-avatar Patch
@rocket.chat/ui-client Patch
@rocket.chat/ui-contexts Patch
@rocket.chat/ui-voip Patch
@rocket.chat/web-ui-registration Patch
@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 Patch
@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

changeset-bot[bot] avatar Dec 01 '25 17:12 changeset-bot[bot]

Walkthrough

Normalize the First_Channel_After_Login setting by stripping a leading # into roomName, block names that start with # or ?, and perform a one-time redirect to /channel/{roomName} in LayoutWithSidebar and LayoutWithSidebarV2; add tests and a patch changeset documenting the fix.

Changes

Cohort / File(s) Change Summary
LayoutWithSidebar component & tests
apps/meteor/client/views/root/MainLayout/LayoutWithSidebar.tsx, apps/meteor/client/views/root/MainLayout/LayoutWithSidebar.spec.tsx
Use useSetting<string>('First_Channel_After_Login', ''), derive roomName by stripping a leading # and trimming, require non-empty roomName, reject names starting with invalid prefixes (#, ?), redirect to /channel/{roomName}, update useEffect dependencies to include roomName, and add tests covering normalization, redirects from / and /home, non-redirect scenarios, and single-redirect behavior across re-renders.
LayoutWithSidebarV2 component & tests
apps/meteor/client/views/root/MainLayout/LayoutWithSidebarV2.tsx, apps/meteor/client/views/root/MainLayout/LayoutWithSidebarV2.spec.tsx
Mirror V1 changes: add INVALID_ROOM_NAME_PREFIXES, compute roomName (strip leading #, trim), guard against invalid prefixes, redirect to /channel/{roomName}, update effect deps, and add tests with mocked UI contexts/components validating the same behaviors and edge cases.
Changeset
.changeset/sixty-bikes-know.md
Add patch changeset noting the fix for First_Channel_After_Login values that began with # (and other invalid prefixes), preventing client routing failures and ensuring correct redirection to the intended channel.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20-30 minutes

  • Pay attention to:
    • useEffect dependency arrays in both components to ensure redirects trigger appropriately and only once.
    • Correctness of roomName normalization for edge cases (e.g., "#", strings with surrounding whitespace, empty values).
    • The invalid-prefix check logic and its interaction with the leading-# stripping.
    • Tests' routing mocks to confirm navigation assertions reflect actual push behavior.

Suggested labels

stat: ready to merge, stat: QA assured

Suggested reviewers

  • pierre-lehnen-rc
  • tassoevan

Poem

🐰 I nibbled a # and set things right,
One gentle redirect, no frantic plight,
Tests hopped in line and gave a cheer,
Sidebar's back — I munch a carrot near 🥕

Pre-merge checks and finishing touches

✅ 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 fix: handling the hash symbol issue in the 'First Channel After Login' setting for correct routing.
Linked Issues check ✅ Passed The PR addresses the core requirement from SUP-916 by fixing routing when First_Channel_After_Login starts with # and preventing other invalid prefixes (?, @) from breaking navigation.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing the First_Channel_After_Login routing issue: validation logic in components, comprehensive test coverage, and changeset documentation.
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
  • [ ] Commit unit tests in branch fix/missing-sidebar-invalid-first-channel

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.

coderabbitai[bot] avatar Dec 01 '25 17:12 coderabbitai[bot]

📦 Docker Image Size Report

📈 Changes

Service Current Baseline Change Percent
sum of all images 1.2GiB 1.2GiB +12MiB
rocketchat 360MiB 349MiB +12MiB
omnichannel-transcript-service 132MiB 132MiB -24B
queue-worker-service 132MiB 132MiB +64B
ddp-streamer-service 126MiB 126MiB -536B
account-service 113MiB 113MiB +454B
stream-hub-service 111MiB 111MiB -291B
presence-service 111MiB 111MiB -657B
authorization-service 111MiB 111MiB -1.1KiB

📊 Historical Trend

---
config:
  theme: "dark"
  xyChart:
    width: 900
    height: 400
---
xychart
  title "Image Size Evolution by Service (Last 30 Days + This PR)"
  x-axis ["11/15 22:28", "11/16 01:28", "11/17 23:50", "11/18 22:53", "11/19 23:02", "11/21 16:49", "11/24 17:34", "11/27 22:32", "11/28 19:05", "12/01 23:01", "12/02 21:57", "12/03 21:00", "12/04 18:17", "12/05 21:56", "12/08 20:15", "12/09 22:17", "12/10 23:26", "12/11 01:16", "12/11 10:47 (PR)"]
  y-axis "Size (GB)" 0 --> 0.5
  line "account-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11]
  line "authorization-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11]
  line "ddp-streamer-service" [0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12]
  line "omnichannel-transcript-service" [0.14, 0.14, 0.14, 0.14, 0.14, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13]
  line "presence-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11]
  line "queue-worker-service" [0.14, 0.14, 0.14, 0.14, 0.14, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13]
  line "rocketchat" [0.36, 0.36, 0.35, 0.35, 0.35, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.35]
  line "stream-hub-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11]

Statistics (last 18 days):

  • 📊 Average: 1.5GiB
  • ⬇️ Minimum: 1.2GiB
  • ⬆️ Maximum: 1.6GiB
  • 🎯 Current PR: 1.2GiB
ℹ️ About this report

This report compares Docker image sizes from this build against the develop baseline.

  • Tag: pr-37656
  • Baseline: develop
  • Timestamp: 2025-12-11 10:47:56 UTC
  • Historical data points: 18

Updated: Thu, 11 Dec 2025 10:47:56 GMT

github-actions[bot] avatar Dec 01 '25 18:12 github-actions[bot]

Codecov Report

:x: Patch coverage is 57.14286% with 6 lines in your changes missing coverage. Please review. :white_check_mark: Project coverage is 68.73%. Comparing base (99dcf8c) to head (e29a177). :warning: Report is 1 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop   #37656      +/-   ##
===========================================
+ Coverage    67.70%   68.73%   +1.03%     
===========================================
  Files         3452     3367      -85     
  Lines       113975   114342     +367     
  Branches     20941    20709     -232     
===========================================
+ Hits         77166    78595    +1429     
+ Misses       34680    33637    -1043     
+ Partials      2129     2110      -19     
Flag Coverage Δ
e2e 57.25% <57.14%> (-0.04%) :arrow_down:
e2e-api 42.28% <ø> (+<0.01%) :arrow_up:

Flags with carried forward coverage won't be shown. Click here to find out more.

:rocket: New features to boost your workflow:
  • :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • :package: JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

codecov[bot] avatar Dec 01 '25 18:12 codecov[bot]

Instead of only checking for #, maybe we should sanitize the string following the existing rules for channel names? For example a user could add !channel to the firstChannelAfterLogin, that would probably still cause the same bug

Hey @MartinSchoeler,

Based on your suggestion, I explored a few possible approaches and here’s what I found:

  1. Slugified channel names When special characters are allowed in channel names, we store:

    • the slugified value in the name field, and
    • the user-provided name in the fname field.

    The client cannot reliably derive name from fname, because if a channel already exists with the same slugified name, the backend appends a suffix (e.g. slugified(fname)-<number>). This makes the final name unpredictable on the client side.

  2. Why the page without a sidebar appears The page without the sidebar is the global not-found page. This happens specifically when the channel name starts with @ or ?:

    • @channelName results in /channel/#channelName

      • Path: /channel
      • Fragment: #channelName
    • ?channelName results in /channel/?channelName

      • Path: /channel
      • Query: ?channelName

    Since we don’t have any routes defined for the path /channel, these cases fall through to the global not-found page.

    In all other cases, routing resolves to the room routes. If the room does not exist, we correctly show the room not-found page along with the sidebar.

  3. If we explicitly handle the two edge cases where the channel name starts with @ or ?, this issue should be fully resolved.

abhinavkrin avatar Dec 10 '25 18:12 abhinavkrin