Skip to content

Conversation

@mandar1045
Copy link

@mandar1045 mandar1045 commented Dec 17, 2025

Summary by CodeRabbit

  • New Features

    • Enhanced admin setup: password policy is now enforced and displayed during account creation, with clear rules and validation feedback.
  • Chores

    • Bumped Node.js runtime requirement to 22.19.0.

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

@mandar1045 mandar1045 requested a review from a team as a code owner December 17, 2025 14:27
@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Dec 17, 2025

Looks like this PR is not ready to merge, because of the following issues:

  • This PR has conflicts, please resolve them before merging
  • This PR is missing the 'stat: QA assured' label
  • This PR is not mergeable
  • 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 Dec 17, 2025

⚠️ No Changeset found

Latest commit: 7087289

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.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

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

CLAassistant commented Dec 17, 2025

CLA assistant check
All committers have signed the CLA.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 17, 2025

Walkthrough

Replaces simple admin-password checks with PasswordPolicy-driven validation and password-rule hints in the admin setup step; wires stepCount and onSubmit props to AdminInfoPage. Also bumps Node.js constraint from 22.16.0 to 22.19.0 in package.json.

Changes

Cohort / File(s) Summary
Password policy-based admin validation
apps/meteor/client/views/setupWizard/steps/AdminInfoStep.tsx
Replaces trivial password validation with policy-driven flow: reads settings, builds a PasswordPolicy via useMemo, calls validatePassword in try/catch to surface policy errors, computes passwordRulesHint, and passes validation, stepCount, and onSubmit to AdminInfoPage.
Node.js version update
package.json
Updates Node.js version constraint from 22.16.0 to 22.19.0 in both engines.node and volta.node.

Estimated code review effort

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

  • Inspect PasswordPolicy instantiation and correct use of settings/constraints.
  • Verify validatePassword error handling and message mapping to UI hints.
  • Confirm passwordRulesHint correctness and prop wiring (stepCount, onSubmit) to AdminInfoPage.
  • Quick check of package.json node-version change for CI compatibility.

Possibly related PRs

Suggested labels

stat: QA assured

Suggested reviewers

  • gabriellsh

Poem

🐰 I hopped through code to polish a rule,
Passwords now learn from a careful tool,
Hints whisper tips, errors gently shown,
Admins set up with standards grown. ✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: add password policy validation in admin setup wizard' accurately and concisely describes the main change: integrating password policy validation into the Admin Setup Wizard component.
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.

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

🧹 Nitpick comments (1)
apps/meteor/client/views/setupWizard/steps/AdminInfoStep.tsx (1)

60-60: Consider removing inline comment.

As per coding guidelines, avoid code comments in implementation files.

-	// Username existence is checked during registration on submit
 	const validateUsername = (username: string): boolean | string => {
📜 Review details

Configuration used: Organization 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 3e42805 and 1e27ad4.

📒 Files selected for processing (2)
  • apps/meteor/client/views/setupWizard/steps/AdminInfoStep.tsx (3 hunks)
  • package.json (1 hunks)
🧰 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:

  • apps/meteor/client/views/setupWizard/steps/AdminInfoStep.tsx
🧠 Learnings (1)
📚 Learning: 2025-10-07T15:08:37.419Z
Learnt from: cardoso
Repo: RocketChat/Rocket.Chat PR: 36942
File: apps/meteor/client/lib/e2ee/pbkdf2.ts:13-45
Timestamp: 2025-10-07T15:08:37.419Z
Learning: In apps/meteor/client/lib/e2ee/pbkdf2.ts, PBKDF2 iteration count validation is not enforced because the iterations parameter is outside the user's control and is system-managed.

Applied to files:

  • apps/meteor/client/views/setupWizard/steps/AdminInfoStep.tsx
🧬 Code graph analysis (1)
apps/meteor/client/views/setupWizard/steps/AdminInfoStep.tsx (1)
packages/ui-contexts/src/index.ts (1)
  • useSetting (72-72)
🔇 Additional comments (1)
package.json (1)

74-78: Verify Node.js 22.19.0 is a released version.

Node.js 22.19.0 is being set in both engines.node and volta.node fields. Confirm this is a valid, released version before merging.

Comment on lines 33 to 58
const passwordPolicy = useMemo(
() =>
new PasswordPolicy({
enabled: true, // Always enable for admin setup
minLength: passwordPolicyEnabled ? Number(passwordPolicyMinLength) : 8,
maxLength: Number(passwordPolicyMaxLength) || -1,
forbidRepeatingCharacters: Boolean(passwordPolicyForbidRepeatingCharacters),
forbidRepeatingCharactersCount: Number(passwordPolicyForbidRepeatingCharactersCount),
mustContainAtLeastOneLowercase: passwordPolicyEnabled ? Boolean(passwordPolicyAtLeastOneLowercase) : true,
mustContainAtLeastOneUppercase: passwordPolicyEnabled ? Boolean(passwordPolicyAtLeastOneUppercase) : true,
mustContainAtLeastOneNumber: passwordPolicyEnabled ? Boolean(passwordPolicyAtLeastOneNumber) : true,
mustContainAtLeastOneSpecialCharacter: Boolean(passwordPolicyAtLeastOneSpecialCharacter),
throwError: false,
}),
[
passwordPolicyEnabled,
passwordPolicyMinLength,
passwordPolicyMaxLength,
passwordPolicyForbidRepeatingCharacters,
passwordPolicyForbidRepeatingCharactersCount,
passwordPolicyAtLeastOneLowercase,
passwordPolicyAtLeastOneUppercase,
passwordPolicyAtLeastOneNumber,
passwordPolicyAtLeastOneSpecialCharacter,
],
);
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 | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find AdminInfoStep.tsx and examine the code
find . -name "AdminInfoStep.tsx" -type f 2>/dev/null | head -5

Repository: RocketChat/Rocket.Chat

Length of output: 128


🏁 Script executed:

#!/bin/bash
# Look for the validatePassword implementation and the PasswordPolicy usage
rg -A 10 "validatePassword\s*=" apps/meteor/client/views/setupWizard/steps/AdminInfoStep.tsx 2>/dev/null || echo "File not found via rg"

Repository: RocketChat/Rocket.Chat

Length of output: 650


🏁 Script executed:

#!/bin/bash
# Check for PasswordPolicy imports and usage in the repository
fd "AdminInfoStep.tsx" 2>/dev/null

Repository: RocketChat/Rocket.Chat

Length of output: 126


🏁 Script executed:

#!/bin/bash
# Search for the file
git ls-files | grep -i "AdminInfoStep" | head -10

Repository: RocketChat/Rocket.Chat

Length of output: 126


🏁 Script executed:

#!/bin/bash
# Search for PasswordPolicy class in the repository
rg "class PasswordPolicy" --type ts --type tsx 2>/dev/null | head -20

Repository: RocketChat/Rocket.Chat

Length of output: 48


🏁 Script executed:

#!/bin/bash
# Look for the @rocket.chat/password-policies package or its usage
rg "from.*@rocket.chat/password-policies" --type ts --type tsx 2>/dev/null | head -5

Repository: RocketChat/Rocket.Chat

Length of output: 48


🏁 Script executed:

#!/bin/bash
# Check if there's a packages directory with password-policies
find . -path "*/node_modules" -prune -o -name "password-policies" -type d -print 2>/dev/null | head -5

Repository: RocketChat/Rocket.Chat

Length of output: 94


🏁 Script executed:

#!/bin/bash
# Look for package.json entries or lib files related to password-policies
find . -path "*/node_modules" -prune -o -name "*.ts" -o -name "*.tsx" | xargs grep -l "throwError" 2>/dev/null | head -10

Repository: RocketChat/Rocket.Chat

Length of output: 444


🏁 Script executed:

#!/bin/bash
# Read the PasswordPolicy implementation
cat ./packages/password-policies/src/PasswordPolicy.ts

Repository: RocketChat/Rocket.Chat

Length of output: 9119


Critical: throwError: false breaks password validation, allowing all passwords to pass validation.

With throwError: false, the validate() method returns false instead of throwing errors. However, validatePassword (lines 69-76) doesn't check this return value—it only expects exceptions via try/catch. This means validation always returns true regardless of whether the password meets policy requirements, creating a security vulnerability where any password is accepted.

Change throwError: false to throwError: true or update validatePassword to inspect the return value of validate().

 		new PasswordPolicy({
 			enabled: true,
 			minLength: passwordPolicyEnabled ? Number(passwordPolicyMinLength) : 8,
 			maxLength: Number(passwordPolicyMaxLength) || -1,
 			forbidRepeatingCharacters: Boolean(passwordPolicyForbidRepeatingCharacters),
 			forbidRepeatingCharactersCount: Number(passwordPolicyForbidRepeatingCharactersCount),
 			mustContainAtLeastOneLowercase: passwordPolicyEnabled ? Boolean(passwordPolicyAtLeastOneLowercase) : true,
 			mustContainAtLeastOneUppercase: passwordPolicyEnabled ? Boolean(passwordPolicyAtLeastOneUppercase) : true,
 			mustContainAtLeastOneNumber: passwordPolicyEnabled ? Boolean(passwordPolicyAtLeastOneNumber) : true,
 			mustContainAtLeastOneSpecialCharacter: Boolean(passwordPolicyAtLeastOneSpecialCharacter),
-			throwError: false,
+			throwError: true,
 		}),
📝 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
const passwordPolicy = useMemo(
() =>
new PasswordPolicy({
enabled: true, // Always enable for admin setup
minLength: passwordPolicyEnabled ? Number(passwordPolicyMinLength) : 8,
maxLength: Number(passwordPolicyMaxLength) || -1,
forbidRepeatingCharacters: Boolean(passwordPolicyForbidRepeatingCharacters),
forbidRepeatingCharactersCount: Number(passwordPolicyForbidRepeatingCharactersCount),
mustContainAtLeastOneLowercase: passwordPolicyEnabled ? Boolean(passwordPolicyAtLeastOneLowercase) : true,
mustContainAtLeastOneUppercase: passwordPolicyEnabled ? Boolean(passwordPolicyAtLeastOneUppercase) : true,
mustContainAtLeastOneNumber: passwordPolicyEnabled ? Boolean(passwordPolicyAtLeastOneNumber) : true,
mustContainAtLeastOneSpecialCharacter: Boolean(passwordPolicyAtLeastOneSpecialCharacter),
throwError: false,
}),
[
passwordPolicyEnabled,
passwordPolicyMinLength,
passwordPolicyMaxLength,
passwordPolicyForbidRepeatingCharacters,
passwordPolicyForbidRepeatingCharactersCount,
passwordPolicyAtLeastOneLowercase,
passwordPolicyAtLeastOneUppercase,
passwordPolicyAtLeastOneNumber,
passwordPolicyAtLeastOneSpecialCharacter,
],
);
const passwordPolicy = useMemo(
() =>
new PasswordPolicy({
enabled: true, // Always enable for admin setup
minLength: passwordPolicyEnabled ? Number(passwordPolicyMinLength) : 8,
maxLength: Number(passwordPolicyMaxLength) || -1,
forbidRepeatingCharacters: Boolean(passwordPolicyForbidRepeatingCharacters),
forbidRepeatingCharactersCount: Number(passwordPolicyForbidRepeatingCharactersCount),
mustContainAtLeastOneLowercase: passwordPolicyEnabled ? Boolean(passwordPolicyAtLeastOneLowercase) : true,
mustContainAtLeastOneUppercase: passwordPolicyEnabled ? Boolean(passwordPolicyAtLeastOneUppercase) : true,
mustContainAtLeastOneNumber: passwordPolicyEnabled ? Boolean(passwordPolicyAtLeastOneNumber) : true,
mustContainAtLeastOneSpecialCharacter: Boolean(passwordPolicyAtLeastOneSpecialCharacter),
throwError: true,
}),
[
passwordPolicyEnabled,
passwordPolicyMinLength,
passwordPolicyMaxLength,
passwordPolicyForbidRepeatingCharacters,
passwordPolicyForbidRepeatingCharactersCount,
passwordPolicyAtLeastOneLowercase,
passwordPolicyAtLeastOneUppercase,
passwordPolicyAtLeastOneNumber,
passwordPolicyAtLeastOneSpecialCharacter,
],
);
🤖 Prompt for AI Agents
In apps/meteor/client/views/setupWizard/steps/AdminInfoStep.tsx around lines
33-58, the PasswordPolicy is created with throwError: false which causes
validate() to return false instead of throwing, and validatePassword only relies
on exceptions so invalid passwords pass; fix by changing throwError to true in
the PasswordPolicy config so validate() throws on failure (or alternatively
modify validatePassword to check the boolean return value of validate() and
treat false as a validation failure), then run tests for password validation to
confirm invalid passwords are rejected.

Comment on lines 78 to 100
const passwordRulesHint = useMemo(() => {
const policy = passwordPolicy.getPasswordPolicy();
const rules: string[] = [];
if (policy.policy.some(([name]) => name === 'get-password-policy-minLength')) {
const minLength = policy.policy.find(([name]) => name === 'get-password-policy-minLength')?.[1]?.minLength;
if (minLength) {
rules.push(`At least ${minLength} characters`);
}
}
if (policy.policy.some(([name]) => name === 'get-password-policy-mustContainAtLeastOneLowercase')) {
rules.push('At least one lowercase letter');
}
if (policy.policy.some(([name]) => name === 'get-password-policy-mustContainAtLeastOneUppercase')) {
rules.push('At least one uppercase letter');
}
if (policy.policy.some(([name]) => name === 'get-password-policy-mustContainAtLeastOneNumber')) {
rules.push('At least one number');
}
if (policy.policy.some(([name]) => name === 'get-password-policy-mustContainAtLeastOneSpecialCharacter')) {
rules.push('At least one special character');
}
return rules.join(', ');
}, [passwordPolicy]);
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

Use translation keys instead of hardcoded English strings.

The password rules hint strings (lines 84, 88, 91, 94, 97) are hardcoded in English. These user-facing strings should use the translation function t() for i18n support.

 	const passwordRulesHint = useMemo(() => {
 		const policy = passwordPolicy.getPasswordPolicy();
 		const rules: string[] = [];
-		if (policy.policy.some(([name]) => name === 'get-password-policy-minLength')) {
-			const minLength = policy.policy.find(([name]) => name === 'get-password-policy-minLength')?.[1]?.minLength;
-			if (minLength) {
-				rules.push(`At least ${minLength} characters`);
-			}
-		}
-		if (policy.policy.some(([name]) => name === 'get-password-policy-mustContainAtLeastOneLowercase')) {
-			rules.push('At least one lowercase letter');
-		}
-		if (policy.policy.some(([name]) => name === 'get-password-policy-mustContainAtLeastOneUppercase')) {
-			rules.push('At least one uppercase letter');
-		}
-		if (policy.policy.some(([name]) => name === 'get-password-policy-mustContainAtLeastOneNumber')) {
-			rules.push('At least one number');
-		}
-		if (policy.policy.some(([name]) => name === 'get-password-policy-mustContainAtLeastOneSpecialCharacter')) {
-			rules.push('At least one special character');
-		}
+		const minLengthRule = policy.policy.find(([name]) => name === 'get-password-policy-minLength');
+		if (minLengthRule?.[1]?.minLength) {
+			rules.push(t('Password_must_have_at_least_n_characters', { n: minLengthRule[1].minLength }));
+		}
+		if (policy.policy.some(([name]) => name === 'get-password-policy-mustContainAtLeastOneLowercase')) {
+			rules.push(t('Password_must_have_at_least_one_lowercase'));
+		}
+		if (policy.policy.some(([name]) => name === 'get-password-policy-mustContainAtLeastOneUppercase')) {
+			rules.push(t('Password_must_have_at_least_one_uppercase'));
+		}
+		if (policy.policy.some(([name]) => name === 'get-password-policy-mustContainAtLeastOneNumber')) {
+			rules.push(t('Password_must_have_at_least_one_number'));
+		}
+		if (policy.policy.some(([name]) => name === 'get-password-policy-mustContainAtLeastOneSpecialCharacter')) {
+			rules.push(t('Password_must_have_at_least_one_special_character'));
+		}
 		return rules.join(', ');
-	}, [passwordPolicy]);
+	}, [passwordPolicy, t]);

Note: Ensure the translation keys are added to the i18n resource files.

📝 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
const passwordRulesHint = useMemo(() => {
const policy = passwordPolicy.getPasswordPolicy();
const rules: string[] = [];
if (policy.policy.some(([name]) => name === 'get-password-policy-minLength')) {
const minLength = policy.policy.find(([name]) => name === 'get-password-policy-minLength')?.[1]?.minLength;
if (minLength) {
rules.push(`At least ${minLength} characters`);
}
}
if (policy.policy.some(([name]) => name === 'get-password-policy-mustContainAtLeastOneLowercase')) {
rules.push('At least one lowercase letter');
}
if (policy.policy.some(([name]) => name === 'get-password-policy-mustContainAtLeastOneUppercase')) {
rules.push('At least one uppercase letter');
}
if (policy.policy.some(([name]) => name === 'get-password-policy-mustContainAtLeastOneNumber')) {
rules.push('At least one number');
}
if (policy.policy.some(([name]) => name === 'get-password-policy-mustContainAtLeastOneSpecialCharacter')) {
rules.push('At least one special character');
}
return rules.join(', ');
}, [passwordPolicy]);
const passwordRulesHint = useMemo(() => {
const policy = passwordPolicy.getPasswordPolicy();
const rules: string[] = [];
const minLengthRule = policy.policy.find(([name]) => name === 'get-password-policy-minLength');
if (minLengthRule?.[1]?.minLength) {
rules.push(t('Password_must_have_at_least_n_characters', { n: minLengthRule[1].minLength }));
}
if (policy.policy.some(([name]) => name === 'get-password-policy-mustContainAtLeastOneLowercase')) {
rules.push(t('Password_must_have_at_least_one_lowercase'));
}
if (policy.policy.some(([name]) => name === 'get-password-policy-mustContainAtLeastOneUppercase')) {
rules.push(t('Password_must_have_at_least_one_uppercase'));
}
if (policy.policy.some(([name]) => name === 'get-password-policy-mustContainAtLeastOneNumber')) {
rules.push(t('Password_must_have_at_least_one_number'));
}
if (policy.policy.some(([name]) => name === 'get-password-policy-mustContainAtLeastOneSpecialCharacter')) {
rules.push(t('Password_must_have_at_least_one_special_character'));
}
return rules.join(', ');
}, [passwordPolicy, t]);
🤖 Prompt for AI Agents
In apps/meteor/client/views/setupWizard/steps/AdminInfoStep.tsx around lines
78-100, the password rules hint strings are hardcoded English text; replace each
literal with calls to the translation function t(...) using stable i18n keys
(e.g. t('setup.passwordRule.minLength', { count: minLength }) for the min-length
message and t('setup.passwordRule.lowercase'),
t('setup.passwordRule.uppercase'), t('setup.passwordRule.number'),
t('setup.passwordRule.special') for the others), ensure interpolation for the
minLength value, import/use the existing translation hook/context
(useTranslation or t from props) as used elsewhere in the component, and add the
corresponding keys and translations to the i18n resource files.

@mandar1045 mandar1045 changed the title Security Vulnerability: Weak Password Validation in Admin Setup Wizard Allows Compromised Admin Accounts fix: add password policy validation in admin setup wizard Dec 17, 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: 0

♻️ Duplicate comments (2)
apps/meteor/client/views/setupWizard/steps/AdminInfoStep.tsx (2)

35-61: Critical: throwError: false breaks password validation.

With throwError: false, validate() returns false on failure instead of throwing. However, validatePassword (lines 73-80) only catches exceptions via try/catch and doesn't check the return value. This means validation always returns true, allowing any password to pass.

 		new PasswordPolicy({
 			enabled: true,
 			minLength: passwordPolicyEnabled ? Number(passwordPolicyMinLength) : 8,
 			maxLength: Number(passwordPolicyMaxLength) || -1,
 			forbidRepeatingCharacters: Boolean(passwordPolicyForbidRepeatingCharacters),
 			forbidRepeatingCharactersCount: Number(passwordPolicyForbidRepeatingCharactersCount),
 			mustContainAtLeastOneLowercase: passwordPolicyEnabled ? Boolean(passwordPolicyAtLeastOneLowercase) : true,
 			mustContainAtLeastOneUppercase: passwordPolicyEnabled ? Boolean(passwordPolicyAtLeastOneUppercase) : true,
 			mustContainAtLeastOneNumber: passwordPolicyEnabled ? Boolean(passwordPolicyAtLeastOneNumber) : true,
 			mustContainAtLeastOneSpecialCharacter: Boolean(passwordPolicyAtLeastOneSpecialCharacter),
-			throwError: false,
+			throwError: true,
 		}),

Also remove the code comment on line 35 per coding guidelines.


82-105: Use translation keys for user-facing strings.

The password rules hint strings are hardcoded in English. Use the translation function t() for i18n support. Also remove the code comment on line 82.

-	// Updated passwordRulesHint to display the required password rules based on policy
 	const passwordRulesHint = useMemo(() => {
 		const policy = passwordPolicy.getPasswordPolicy();
 		const rules: string[] = [];
-		if (policy.policy.some(([name]) => name === 'get-password-policy-minLength')) {
-			const minLength = policy.policy.find(([name]) => name === 'get-password-policy-minLength')?.[1]?.minLength;
-			if (minLength) {
-				rules.push(`At least ${minLength} characters`);
-			}
+		const minLengthRule = policy.policy.find(([name]) => name === 'get-password-policy-minLength');
+		if (minLengthRule?.[1]?.minLength) {
+			rules.push(t('Password_must_have_at_least_n_characters', { n: minLengthRule[1].minLength }));
 		}
 		if (policy.policy.some(([name]) => name === 'get-password-policy-mustContainAtLeastOneLowercase')) {
-			rules.push('At least one lowercase letter');
+			rules.push(t('Password_must_have_at_least_one_lowercase'));
 		}
 		if (policy.policy.some(([name]) => name === 'get-password-policy-mustContainAtLeastOneUppercase')) {
-			rules.push('At least one uppercase letter');
+			rules.push(t('Password_must_have_at_least_one_uppercase'));
 		}
 		if (policy.policy.some(([name]) => name === 'get-password-policy-mustContainAtLeastOneNumber')) {
-			rules.push('At least one number');
+			rules.push(t('Password_must_have_at_least_one_number'));
 		}
 		if (policy.policy.some(([name]) => name === 'get-password-policy-mustContainAtLeastOneSpecialCharacter')) {
-			rules.push('At least one special character');
+			rules.push(t('Password_must_have_at_least_one_special_character'));
 		}
 		return rules.join(', ');
-	}, [passwordPolicy]);
+	}, [passwordPolicy, t]);

Ensure the translation keys are added to packages/i18n/src/locales/en.i18n.json. Based on learnings, other locale files are populated via the external translation pipeline.

🧹 Nitpick comments (4)
apps/meteor/client/views/setupWizard/steps/AdminInfoStep.tsx (4)

2-3: Remove unnecessary code comment.

Per coding guidelines, avoid code comments in the implementation. The import is self-explanatory.

-// Added import for password policy validation to enforce strong admin passwords
 import { PasswordPolicy } from '@rocket.chat/password-policies';

22-31: Remove code comment.

Per coding guidelines, avoid code comments in the implementation.

-	// Added useSetting hooks for password policy settings to configure validation rules
 	const passwordPolicyEnabled = useSetting('Accounts_Password_Policy_Enabled');

63-64: Remove code comment.

-	// Username existence is checked during registration on submit
 	const validateUsername = (username: string): boolean | string => {

72-80: Remove code comment and verify logic works with throwError: true.

Once throwError: true is set in the PasswordPolicy config, this try/catch pattern will correctly catch validation errors.

-	// Updated validatePassword to use password policy validation for stronger admin passwords
 	const validatePassword = (password: string): boolean | string => {
📜 Review details

Configuration used: Organization 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 1e27ad4 and 29d2369.

📒 Files selected for processing (2)
  • apps/meteor/client/views/setupWizard/steps/AdminInfoStep.tsx (3 hunks)
  • package.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • package.json
🧰 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:

  • apps/meteor/client/views/setupWizard/steps/AdminInfoStep.tsx
🧠 Learnings (3)
📚 Learning: 2025-10-07T15:08:37.419Z
Learnt from: cardoso
Repo: RocketChat/Rocket.Chat PR: 36942
File: apps/meteor/client/lib/e2ee/pbkdf2.ts:13-45
Timestamp: 2025-10-07T15:08:37.419Z
Learning: In apps/meteor/client/lib/e2ee/pbkdf2.ts, PBKDF2 iteration count validation is not enforced because the iterations parameter is outside the user's control and is system-managed.

Applied to files:

  • apps/meteor/client/views/setupWizard/steps/AdminInfoStep.tsx
📚 Learning: 2025-11-07T14:50:33.544Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37423
File: packages/i18n/src/locales/en.i18n.json:18-18
Timestamp: 2025-11-07T14:50:33.544Z
Learning: Rocket.Chat settings: in apps/meteor/ee/server/settings/abac.ts, the Abac_Cache_Decision_Time_Seconds setting uses invalidValue: 0 as the fallback when ABAC is unlicensed. With a valid license, admins can still set the value to 0 to intentionally disable the ABAC decision cache.

Applied to files:

  • apps/meteor/client/views/setupWizard/steps/AdminInfoStep.tsx
📚 Learning: 2025-11-19T12:32:29.696Z
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 37547
File: packages/i18n/src/locales/en.i18n.json:634-634
Timestamp: 2025-11-19T12:32:29.696Z
Learning: Repo: RocketChat/Rocket.Chat
Context: i18n workflow
Learning: In this repository, new translation keys should be added to packages/i18n/src/locales/en.i18n.json only; other locale files are populated via the external translation pipeline and/or fall back to English. Do not request adding the same key to all locale files in future reviews.

Applied to files:

  • apps/meteor/client/views/setupWizard/steps/AdminInfoStep.tsx
🧬 Code graph analysis (1)
apps/meteor/client/views/setupWizard/steps/AdminInfoStep.tsx (1)
packages/ui-contexts/src/index.ts (1)
  • useSetting (72-72)
🔇 Additional comments (1)
apps/meteor/client/views/setupWizard/steps/AdminInfoStep.tsx (1)

111-124: LGTM!

The props are correctly wired to AdminInfoPage, integrating the password validation and hint display with the wizard flow.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants