Skip to content

Conversation

@dougfabris
Copy link
Member

@dougfabris dougfabris commented Dec 9, 2025

Proposed changes (including videos or screenshots)

Fixes an issue where the user is being locked on the TOTP modal because headers are not being handled properly.
This PR, aims to create a helper function to check the type of the headers and provide them normalized, avoiding issues.

Issue(s)

Steps to test or reproduce

  • Go to account security
  • Change your password
  • Should change the password successfully

Further comments

CORE-1539

Summary by CodeRabbit

  • Bug Fixes
    • Fixed password change functionality on the account security page that was previously unavailable.
    • Improved HTTP header handling for two-factor authentication code and method extraction.

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

@dougfabris dougfabris added this to the 7.14.0 milestone Dec 9, 2025
@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Dec 9, 2025

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

@changeset-bot
Copy link

changeset-bot bot commented Dec 9, 2025

🦋 Changeset detected

Latest commit: d67fe52

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 9, 2025

Walkthrough

This PR fixes a regression preventing password changes when 2FA is enabled by introducing HTTP header normalization for 2FA code extraction. A new normalizeHeaders helper standardizes header handling, and the password change test is re-enabled.

Changes

Cohort / File(s) Summary
Header Normalization Infrastructure
apps/meteor/app/lib/server/functions/getModifiedHttpHeaders.ts
Adds normalizeHeaders() helper to convert Headers instances or plain objects into standardized plain objects. Updates getModifiedHttpHeaders() to use the helper and extends cookie redaction to include rc_token values.
2FA Code Handler
apps/meteor/app/2fa/server/code/index.ts
Implements normalized header extraction for 2FA code and method parameters using the new normalizeHeaders() helper instead of direct header access.
Test Re-enablement
apps/meteor/tests/e2e/account-security.spec.ts
Re-enables the skipped "should be able to change password" end-to-end test by removing test.skip.
Release Documentation
.changeset/cold-chairs-taste.md
Declares a patch release documenting the password change fix.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

  • Focus on the normalizeHeaders() logic to verify correct conversion of Headers instances and object copying behavior
  • Verify the cookie redaction logic properly handles rc_token values alongside existing redaction patterns
  • Confirm that the 2FA code handler correctly extracts normalized headers in all scenarios (code and method provided/not provided)

Possibly related PRs

Suggested labels

stat: ready to merge, stat: QA assured

Suggested reviewers

  • KevLehman

Poem

🐰 Headers normalize with care,
Two-factor passwords in the air,
The loop is fixed, the test runs true,
Security flows just as it should do! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main issue being fixed: enabling password changes when 2FA is enabled.
Linked Issues check ✅ Passed The changes address the core requirement from CORE-1539: fixing the password change loop when 2FA is enabled by normalizing HTTP headers during verification.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing the 2FA password-change issue: normalizing headers, re-enabling the test, and documenting the fix in the changeset.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ 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/cannot-change-password

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.

@github-actions
Copy link
Contributor

github-actions bot commented Dec 9, 2025

📦 Docker Image Size Report

📈 Changes

Service Current Baseline Change Percent
sum of all images 1.2GiB 1.2GiB +12MiB
rocketchat 358MiB 347MiB +12MiB
omnichannel-transcript-service 132MiB 132MiB +496B
queue-worker-service 132MiB 132MiB +1.3KiB
ddp-streamer-service 126MiB 126MiB +372B
account-service 113MiB 113MiB -609B
stream-hub-service 111MiB 111MiB -94B
presence-service 111MiB 111MiB -357B
authorization-service 111MiB 111MiB +248B

📊 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 21:16", "12/11 21:18 (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]
Loading

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-37745
  • Baseline: develop
  • Timestamp: 2025-12-11 21:18:35 UTC
  • Historical data points: 18

Updated: Thu, 11 Dec 2025 21:18:35 GMT

@codecov
Copy link

codecov bot commented Dec 9, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 67.80%. Comparing base (94b87d9) to head (d67fe52).
⚠️ Report is 1 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop   #37745      +/-   ##
===========================================
+ Coverage    67.70%   67.80%   +0.10%     
===========================================
  Files         3452     3452              
  Lines       113982   113979       -3     
  Branches     20943    20943              
===========================================
+ Hits         77171    77286     +115     
+ Misses       34681    34556     -125     
- Partials      2130     2137       +7     
Flag Coverage Δ
e2e 57.34% <ø> (+0.07%) ⬆️
e2e-api 43.29% <ø> (+0.96%) ⬆️

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

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

@dougfabris dougfabris marked this pull request as ready for review December 11, 2025 19:24
@dougfabris dougfabris requested a review from a team as a code owner December 11, 2025 19:24
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: 1

🧹 Nitpick comments (1)
apps/meteor/app/lib/server/functions/getModifiedHttpHeaders.ts (1)

1-11: Make normalizeHeaders handling of undefined more explicit (optional)

The helper behaves correctly today, including when httpHeaders is undefined (via { ...httpHeaders }{}), but that relies on somewhat non-obvious spread semantics. For readability, you could make the undefined case explicit:

-export const normalizeHeaders = (httpHeaders?: Headers | Record<string, string>) => {
-	if (httpHeaders instanceof Headers) {
-		return { ...Object.fromEntries(httpHeaders.entries()) };
-	}
-
-	return { ...httpHeaders };
-};
+export const normalizeHeaders = (httpHeaders?: Headers | Record<string, string>) => {
+	if (!httpHeaders) {
+		return {};
+	}
+
+	if (httpHeaders instanceof Headers) {
+		return { ...Object.fromEntries(httpHeaders.entries()) };
+	}
+
+	return { ...httpHeaders };
+};

This keeps behavior the same while making the intent clearer to future readers.

📜 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 2e4bd49 and 004fc42.

📒 Files selected for processing (4)
  • .changeset/cold-chairs-taste.md (1 hunks)
  • apps/meteor/app/2fa/server/code/index.ts (2 hunks)
  • apps/meteor/app/lib/server/functions/getModifiedHttpHeaders.ts (1 hunks)
  • apps/meteor/tests/e2e/account-security.spec.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{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/app/lib/server/functions/getModifiedHttpHeaders.ts
  • apps/meteor/tests/e2e/account-security.spec.ts
  • apps/meteor/app/2fa/server/code/index.ts
**/*.spec.ts

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

**/*.spec.ts: Use descriptive test names that clearly communicate expected behavior in Playwright tests
Use .spec.ts extension for test files (e.g., login.spec.ts)

Files:

  • apps/meteor/tests/e2e/account-security.spec.ts
apps/meteor/tests/e2e/**/*.spec.ts

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

apps/meteor/tests/e2e/**/*.spec.ts: All test files must be created in apps/meteor/tests/e2e/ directory
Avoid using page.locator() in Playwright tests - always prefer semantic locators such as page.getByRole(), page.getByLabel(), page.getByText(), or page.getByTitle()
Use test.beforeAll() and test.afterAll() for setup/teardown in Playwright tests
Use test.step() for complex test scenarios to improve organization in Playwright tests
Group related tests in the same file
Utilize Playwright fixtures (test, page, expect) for consistency in test files
Prefer web-first assertions (toBeVisible, toHaveText, etc.) in Playwright tests
Use expect matchers for assertions (toEqual, toContain, toBeTruthy, toHaveLength, etc.) instead of assert statements in Playwright tests
Use page.waitFor() with specific conditions instead of hardcoded timeouts in Playwright tests
Implement proper wait strategies for dynamic content in Playwright tests
Maintain test isolation between test cases in Playwright tests
Ensure clean state for each test execution in Playwright tests
Ensure tests run reliably in parallel without shared state conflicts

Files:

  • apps/meteor/tests/e2e/account-security.spec.ts
apps/meteor/tests/e2e/**/*.{ts,spec.ts}

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

apps/meteor/tests/e2e/**/*.{ts,spec.ts}: Store commonly used locators in variables/constants for reuse
Follow Page Object Model pattern consistently in Playwright tests

Files:

  • apps/meteor/tests/e2e/account-security.spec.ts
🧠 Learnings (10)
📚 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/e2e/account-security.spec.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 : All test files must be created in `apps/meteor/tests/e2e/` directory

Applied to files:

  • apps/meteor/tests/e2e/account-security.spec.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/e2e/account-security.spec.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 `test.step()` for complex test scenarios to improve organization in Playwright tests

Applied to files:

  • apps/meteor/tests/e2e/account-security.spec.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/e2e/account-security.spec.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/e2e/account-security.spec.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 : Prefer web-first assertions (`toBeVisible`, `toHaveText`, etc.) in Playwright tests

Applied to files:

  • apps/meteor/tests/e2e/account-security.spec.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 : Maintain test isolation between test cases in Playwright tests

Applied to files:

  • apps/meteor/tests/e2e/account-security.spec.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/**/*.{ts,spec.ts} : Follow Page Object Model pattern consistently in Playwright tests

Applied to files:

  • apps/meteor/tests/e2e/account-security.spec.ts
📚 Learning: 2025-12-10T21:00:43.645Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37091
File: ee/packages/abac/jest.config.ts:4-7
Timestamp: 2025-12-10T21:00:43.645Z
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:

  • apps/meteor/tests/e2e/account-security.spec.ts
🧬 Code graph analysis (1)
apps/meteor/app/2fa/server/code/index.ts (1)
apps/meteor/app/lib/server/functions/getModifiedHttpHeaders.ts (1)
  • normalizeHeaders (1-7)
🔇 Additional comments (2)
apps/meteor/app/2fa/server/code/index.ts (1)

12-13: Header normalization fix for 2FA looks correct

Using normalizeHeaders(connection?.httpHeaders) and then reading x-2fa-code / x-2fa-method only when code and method are absent correctly handles both Headers and plain-object header representations and should resolve the looping 2FA/password-change issue without affecting existing explicit-parameter flows.

Also applies to: 188-193

apps/meteor/tests/e2e/account-security.spec.ts (1)

41-52: Re‑enabled password-change e2e test is well-structured

The test steps cleanly exercise the password-change flow (including reverting the admin password via API), use test.step and Playwright expect correctly, and fit the serial describe to avoid shared-state issues. This should reliably guard against regressions in the 2FA password-change flow.

@dougfabris dougfabris added the stat: QA assured Means it has been tested and approved by a company insider label Dec 11, 2025
@dionisio-bot dionisio-bot bot added the stat: ready to merge PR tested and approved waiting for merge label Dec 11, 2025
@kodiakhq kodiakhq bot merged commit 17f587b into develop Dec 11, 2025
50 checks passed
@kodiakhq kodiakhq bot deleted the fix/cannot-change-password branch December 11, 2025 21:42
@dougfabris dougfabris modified the milestones: 7.14.0, 8.0.0 Jan 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stat: QA assured Means it has been tested and approved by a company insider stat: ready to merge PR tested and approved waiting for merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants