regression: Prevent saving license with non-plausible value - #41306
Conversation
|
Looks like this PR is ready to merge! 🎉 |
|
WalkthroughThe PR updates enterprise settings to render editable license-management sections, changes subscription license controls and permissions, tightens license validation and current-license handling, adds accessibility and regression coverage, and updates English locale keys. ChangesManual license management
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant ManageLicenseModal
participant useValidateLicense
participant LicenseValidationAPI
ManageLicenseModal->>useValidateLicense: provide license and enabled state
useValidateLicense->>LicenseValidationAPI: validate plausible non-current license
LicenseValidationAPI-->>useValidateLicense: return validation result
useValidateLicense-->>ManageLicenseModal: expose validation state
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Warning Review ran into problems🔥 ProblemsErrors were encountered while retrieving linked issues. Errors (1)
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. Comment |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## develop #41306 +/- ##
===========================================
- Coverage 69.04% 68.17% -0.87%
===========================================
Files 3757 3969 +212
Lines 147735 154820 +7085
Branches 26395 27893 +1498
===========================================
+ Hits 102000 105556 +3556
- Misses 41234 44468 +3234
- Partials 4501 4796 +295
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
apps/meteor/client/views/admin/subscription/components/cards/PlanCard/PlanCardLicenseDetails.tsx (1)
41-41: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRedundant
!hasCopied*guard in copy button onClick handlers.The ternary on lines 38–42 (and 51–55) already ensures the clipboard
IconButtononly renders whenhasCopiedisfalse. The!hasCopiedSiteURL &&/!hasCopiedHashed &&guards inside theonClickare therefore alwaystrueat render time and can be simplified to direct calls.♻️ Simplify onClick handlers
- <IconButton title={t('Copy')} icon='clipboard' mini onClick={() => !hasCopiedSiteURL && copySiteURL()} /> + <IconButton title={t('Copy')} icon='clipboard' mini onClick={() => copySiteURL()} />- <IconButton title={t('Copy')} icon='clipboard' mini onClick={() => !hasCopiedHashed && copyHashed()} /> + <IconButton title={t('Copy')} icon='clipboard' mini onClick={() => copyHashed()} />Also applies to: 54-54
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/meteor/client/views/admin/subscription/components/cards/PlanCard/PlanCardLicenseDetails.tsx` at line 41, In PlanCardLicenseDetails, simplify the clipboard IconButton onClick handlers by removing the redundant !hasCopiedSiteURL and !hasCopiedHashed guards and directly invoking copySiteURL() and copyHashed(). Keep the existing conditional rendering based on each hasCopied state unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/meteor/client/views/admin/settings/groups/EnterpriseGroupPage.tsx`:
- Line 49: Update the section key in EnterpriseGroupPage’s
useEditableSettingsGroupSections rendering so unnamed sections receive unique,
stable keys rather than all falling back to an empty string; preserve
sectionName as the key when it is present.
---
Nitpick comments:
In
`@apps/meteor/client/views/admin/subscription/components/cards/PlanCard/PlanCardLicenseDetails.tsx`:
- Line 41: In PlanCardLicenseDetails, simplify the clipboard IconButton onClick
handlers by removing the redundant !hasCopiedSiteURL and !hasCopiedHashed guards
and directly invoking copySiteURL() and copyHashed(). Keep the existing
conditional rendering based on each hasCopied state unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: d2428fe7-fc3c-4f18-a824-b10b9dcab055
📒 Files selected for processing (6)
apps/meteor/client/views/admin/settings/SettingsSection/SettingsSection.tsxapps/meteor/client/views/admin/settings/groups/EnterpriseGroupPage.tsxapps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.spec.tsxapps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.tsxapps/meteor/client/views/admin/subscription/components/cards/PlanCard/PlanCardLicenseDetails.tsxpackages/i18n/src/locales/en.i18n.json
📜 Review details
⏰ Context from checks skipped due to timeout. (5)
- GitHub Check: cubic · AI code reviewer
- GitHub Check: Hacktron Security Check
- GitHub Check: 📦 Build Packages
- GitHub Check: CodeQL-Build
- GitHub Check: CodeQL-Build
🧰 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/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.spec.tsxapps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.tsxapps/meteor/client/views/admin/settings/SettingsSection/SettingsSection.tsxapps/meteor/client/views/admin/subscription/components/cards/PlanCard/PlanCardLicenseDetails.tsxapps/meteor/client/views/admin/settings/groups/EnterpriseGroupPage.tsx
🧠 Learnings (3)
📚 Learning: 2026-03-06T18:10:15.268Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 39397
File: packages/gazzodown/src/code/CodeBlock.spec.tsx:47-68
Timestamp: 2026-03-06T18:10:15.268Z
Learning: In tests (especially those using testing-library/dom/jsdom) for Rocket.Chat components, the HTML <code> element has an implicit ARIA role of 'code'. Therefore, screen.getByRole('code') or screen.findByRole('code') will locate <code> elements even without a role attribute. Do not flag findByRole('code') as invalid in reviews; prefer using the implicit role instead of adding role="code" unless necessary for accessibility.
Applied to files:
apps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.spec.tsx
📚 Learning: 2026-03-27T14:52:56.865Z
Learnt from: dougfabris
Repo: RocketChat/Rocket.Chat PR: 39892
File: apps/meteor/client/views/room/contextualBar/Threads/Thread.tsx:150-155
Timestamp: 2026-03-27T14:52:56.865Z
Learning: In Rocket.Chat, there are two different `ModalBackdrop` components with different prop APIs. During review, confirm the import source: (1) `rocket.chat/fuselage` `ModalBackdrop` uses `ModalBackdropProps` based on `BoxProps` (so it supports `onClick` and other Box/DOM props) and does not have an `onDismiss` prop; (2) `rocket.chat/ui-client` `ModalBackdrop` uses a narrower props interface like `{ children?: ReactNode; onDismiss?: () => void }` and handles Escape keypress and outside mouse-up, and it does not forward arbitrary DOM props such as `onClick`. Flag mismatched props (e.g., `onDismiss` passed to the fuselage component or `onClick` passed to the ui-client component) and ensure the usage matches the correct component being imported.
Applied to files:
apps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.spec.tsxapps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.tsxapps/meteor/client/views/admin/settings/SettingsSection/SettingsSection.tsxapps/meteor/client/views/admin/subscription/components/cards/PlanCard/PlanCardLicenseDetails.tsxapps/meteor/client/views/admin/settings/groups/EnterpriseGroupPage.tsx
📚 Learning: 2026-05-06T12:21:44.083Z
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 40256
File: apps/meteor/client/components/CreateDiscussion/CreateDiscussion.tsx:121-149
Timestamp: 2026-05-06T12:21:44.083Z
Learning: Field wrappers in rocket.chat/fuselage-forms (Field, FieldLabel, FieldRow, FieldError, FieldHint) auto-create htmlFor/id associations, aria-describedby, and role="alert" for errors. Do not manually set htmlFor, id, aria-describedby, or role attributes when using these wrappers. This automatic wiring does not apply to plain rocket.chat/fuselage components, which require explicit ID wiring per the accessibility docs. In code reviews, prefer using fuselage-forms wrappers for form fields and verify there is no unnecessary manual ID/aria wiring in files that use these wrappers. If a component uses plain fuselage components, ensure proper id wiring as per docs.
Applied to files:
apps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.spec.tsxapps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.tsxapps/meteor/client/views/admin/settings/SettingsSection/SettingsSection.tsxapps/meteor/client/views/admin/subscription/components/cards/PlanCard/PlanCardLicenseDetails.tsxapps/meteor/client/views/admin/settings/groups/EnterpriseGroupPage.tsx
🔇 Additional comments (5)
apps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.tsx (1)
54-54: LGTM!apps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.spec.tsx (1)
114-127: LGTM!packages/i18n/src/locales/en.i18n.json (1)
491-492: No remainingAdd_licensereferences.apps/meteor/client/views/admin/settings/SettingsSection/SettingsSection.tsx (1)
16-23: LGTM!Also applies to: 78-78
apps/meteor/client/views/admin/settings/groups/EnterpriseGroupPage.tsx (1)
53-53: 📐 Maintainability & Code Quality
Manual_license_management_deprecatedis defined inpackages/i18n/src/locales/en.i18n.json.
There was a problem hiding this comment.
Review completed against the latest diff
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
apps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.stories.tsx (1)
71-74: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRemove unnecessary
awaitbeforeexpect.The
expectassertion and its matchertoBeInTheDocument()are synchronous. Only thefindByTextquery is asynchronous and requiresawait.♻️ Proposed refactor
play: async () => { await enterLicense(SAMPLE_LICENSE); - await expect(await screen.findByText('Invalid_license')).toBeInTheDocument(); + expect(await screen.findByText('Invalid_license')).toBeInTheDocument(); },🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.stories.tsx` around lines 71 - 74, In the play function, update the assertion using screen.findByText so only the asynchronous query is awaited; remove the unnecessary await from the synchronous expect(...).toBeInTheDocument() chain.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@apps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.spec.tsx`:
- Around line 38-43: Update the accessibility test around the parameterized test
in ManageLicenseModal.spec.tsx to destructure baseElement from render and pass
it to axe instead of container. Keep the existing Story rendering, wrapper, and
no-violations assertion unchanged so portaled modal content is included in the
audit.
---
Nitpick comments:
In
`@apps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.stories.tsx`:
- Around line 71-74: In the play function, update the assertion using
screen.findByText so only the asynchronous query is awaited; remove the
unnecessary await from the synchronous expect(...).toBeInTheDocument() chain.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: bbedcd48-11b0-4673-8068-da5244fb309c
⛔ Files ignored due to path filters (1)
apps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/__snapshots__/ManageLicenseModal.spec.tsx.snapis excluded by!**/*.snap
📒 Files selected for processing (4)
apps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/LicenseStatus.tsxapps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.spec.tsxapps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.stories.tsxapps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.tsx
📜 Review details
⏰ Context from checks skipped due to timeout. (5)
- GitHub Check: 📦 Build Packages
- GitHub Check: cubic · AI code reviewer
- GitHub Check: Hacktron Security Check
- GitHub Check: CodeQL-Build
- GitHub Check: CodeQL-Build
⚠️ CI failures not shown inline (4)
GitHub Check: Dionisio QA: Some checks did not pass
Conclusion: failure
**Conclusion:** failure
### Steps
- ✅ **No merge conflicts**
- ❌ **QA assured** — This PR is missing the 'stat: QA assured' label
- ✅ **Mergeable**
- ✅ **Has milestone or project**
- ✅ **Valid PR title**
- ✅ **Correct target version**
GitHub Check: Dionisio QA: Some checks did not pass
Conclusion: failure
**Conclusion:** failure
### Steps
- ✅ **No merge conflicts**
- ❌ **QA assured** — This PR is missing the 'stat: QA assured' label
- ✅ **Mergeable**
- ✅ **Has milestone or project**
- ✅ **Valid PR title**
- ✅ **Correct target version**
GitHub Check: Dionisio QA: Some checks did not pass
Conclusion: failure
**Conclusion:** failure
### Steps
- ✅ **No merge conflicts**
- ❌ **QA assured** — This PR is missing the 'stat: QA assured' label
- ✅ **Mergeable**
- ✅ **Has milestone or project**
- ✅ **Valid PR title**
- ✅ **Correct target version**
GitHub Check: Dionisio QA: Some checks did not pass
Conclusion: failure
**Conclusion:** failure
### Steps
- ✅ **No merge conflicts**
- ❌ **QA assured** — This PR is missing the 'stat: QA assured' label
- ✅ **Mergeable**
- ✅ **Has milestone or project**
- ✅ **Valid PR title**
- ✅ **Correct target version**
🧰 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/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.stories.tsxapps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/LicenseStatus.tsxapps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.tsxapps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.spec.tsx
🧠 Learnings (3)
📚 Learning: 2026-03-27T14:52:56.865Z
Learnt from: dougfabris
Repo: RocketChat/Rocket.Chat PR: 39892
File: apps/meteor/client/views/room/contextualBar/Threads/Thread.tsx:150-155
Timestamp: 2026-03-27T14:52:56.865Z
Learning: In Rocket.Chat, there are two different `ModalBackdrop` components with different prop APIs. During review, confirm the import source: (1) `rocket.chat/fuselage` `ModalBackdrop` uses `ModalBackdropProps` based on `BoxProps` (so it supports `onClick` and other Box/DOM props) and does not have an `onDismiss` prop; (2) `rocket.chat/ui-client` `ModalBackdrop` uses a narrower props interface like `{ children?: ReactNode; onDismiss?: () => void }` and handles Escape keypress and outside mouse-up, and it does not forward arbitrary DOM props such as `onClick`. Flag mismatched props (e.g., `onDismiss` passed to the fuselage component or `onClick` passed to the ui-client component) and ensure the usage matches the correct component being imported.
Applied to files:
apps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.stories.tsxapps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/LicenseStatus.tsxapps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.tsxapps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.spec.tsx
📚 Learning: 2026-05-06T12:21:44.083Z
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 40256
File: apps/meteor/client/components/CreateDiscussion/CreateDiscussion.tsx:121-149
Timestamp: 2026-05-06T12:21:44.083Z
Learning: Field wrappers in rocket.chat/fuselage-forms (Field, FieldLabel, FieldRow, FieldError, FieldHint) auto-create htmlFor/id associations, aria-describedby, and role="alert" for errors. Do not manually set htmlFor, id, aria-describedby, or role attributes when using these wrappers. This automatic wiring does not apply to plain rocket.chat/fuselage components, which require explicit ID wiring per the accessibility docs. In code reviews, prefer using fuselage-forms wrappers for form fields and verify there is no unnecessary manual ID/aria wiring in files that use these wrappers. If a component uses plain fuselage components, ensure proper id wiring as per docs.
Applied to files:
apps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.stories.tsxapps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/LicenseStatus.tsxapps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.tsxapps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.spec.tsx
📚 Learning: 2026-03-06T18:10:15.268Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 39397
File: packages/gazzodown/src/code/CodeBlock.spec.tsx:47-68
Timestamp: 2026-03-06T18:10:15.268Z
Learning: In tests (especially those using testing-library/dom/jsdom) for Rocket.Chat components, the HTML <code> element has an implicit ARIA role of 'code'. Therefore, screen.getByRole('code') or screen.findByRole('code') will locate <code> elements even without a role attribute. Do not flag findByRole('code') as invalid in reviews; prefer using the implicit role instead of adding role="code" unless necessary for accessibility.
Applied to files:
apps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.spec.tsx
🔇 Additional comments (2)
apps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/LicenseStatus.tsx (1)
13-32: LGTM!apps/meteor/client/views/admin/subscription/components/cards/PlanCard/ManageLicenseModal/ManageLicenseModal.tsx (1)
51-51: 🚀 Performance & ScalabilityNo additional guard needed —
useValidateLicensealready skips requests for non-plausible input viaenabled && isPlausibleLicense(trimmedLicense).> Likely an incorrect or invalid review comment.
Proposed changes (including videos or screenshots)
edit-privileged-settingpermissionuseClipboardWithToastfor copy actions and guard against duplicate copiesIssue(s)
Steps to test or reproduce
Further comments
CORE-2403
CORE-2404
Summary by CodeRabbit
Summary by CodeRabbit