Skip to content

UI: Set Mac Recovery Lock passwords - #41166

Merged
jacobshandling merged 20 commits into
mainfrom
39723-set-mac-recovery-lock-passwords-frontend
Mar 10, 2026
Merged

UI: Set Mac Recovery Lock passwords#41166
jacobshandling merged 20 commits into
mainfrom
39723-set-mac-recovery-lock-passwords-frontend

Conversation

@jacobshandling

@jacobshandling jacobshandling commented Mar 6, 2026

Copy link
Copy Markdown
Contributor

Related issue: Resolves #39723

Checklist for submitter

If some of the following don't apply, delete the relevant line.

  • Changes file added for user-visible changes in changes/
  • Added/updated automated tests
  • QA'd all new/changed functionality manually
    • With spoofed data
    • Integrated with backend (wip)

Summary by CodeRabbit

  • New Features

    • Recovery Lock Passwords: new OS Settings card to enable/disable enforcement and save changes.
    • Host Actions: view a host's Recovery Lock password via a modal from the host actions menu.
    • Activity tracking: new activity entries for viewing, setting, enabling, and disabling Recovery Lock passwords.
    • Navigation: added a dedicated route for Passwords under OS Settings.
  • Documentation

    • Updated guidance for updating local config after an update to ensure latest values.

@jacobshandling
jacobshandling requested a review from a team as a code owner March 6, 2026 20:22
@codecov

codecov Bot commented Mar 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 52.42718% with 49 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.31%. Comparing base (ebe49ca) to head (5cfc842).
⚠️ Report is 163 commits behind head on main.

Files with missing lines Patch % Lines
.../hosts/details/HostDetailsPage/HostDetailsPage.tsx 0.00% 13 Missing ⚠️
...eryLockPasswordModal/RecoveryLockPasswordModal.tsx 14.28% 12 Missing ⚠️
...ngsModal/OSSettingsTable/OSSettingsTableConfig.tsx 11.11% 8 Missing ⚠️
...ls/HostDetailsPage/HostActionsDropdown/helpers.tsx 80.00% 6 Missing ⚠️
frontend/services/entities/hosts.ts 0.00% 3 Missing ⚠️
...coveryLockPassword/SetHostRecoveryLockPassword.tsx 33.33% 2 Missing ⚠️
...eryLockPassword/ViewedHostRecoveryLockPassword.tsx 33.33% 2 Missing ⚠️
frontend/pages/hosts/details/helpers.ts 33.33% 2 Missing ⚠️
frontend/utilities/endpoints.ts 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #41166      +/-   ##
==========================================
- Coverage   66.31%   66.31%   -0.01%     
==========================================
  Files        2470     2476       +6     
  Lines      197878   198233     +355     
  Branches     8774     8924     +150     
==========================================
+ Hits       131232   131454     +222     
- Misses      54767    54900     +133     
  Partials    11879    11879              
Flag Coverage Δ
frontend 54.30% <52.42%> (+0.11%) ⬆️

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

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 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.

@jacobshandling

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Mar 6, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Mar 6, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Adds frontend support for Recovery Lock password features: new MDM config fields at global and team scope, new activity types and activity item components, a Passwords card under OS Settings with toggle and save behavior, a host Recovery Lock Password modal and related host action option, a new hosts service method and endpoint for fetching passwords, updated OS settings navigation and side‑nav typing, and UI/SCSS for the new screens and components.

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title 'UI: Set Mac Recovery Lock passwords' clearly describes the main change: implementing the frontend UI for setting macOS Recovery Lock passwords, which matches the core objective from linked issue #39723.
Description check ✅ Passed The pull request description includes the related issue (#39723), marks completion of required checklist items (changes file and automated tests), and acknowledges testing status with spoofed data and WIP backend integration.
Linked Issues check ✅ Passed The code changes comprehensively implement the frontend UI for macOS Recovery Lock password management, including new components (Passwords.tsx, RecoveryLockPasswordModal), activity tracking, navigation integration, host details UI, and supporting interfaces/types aligned with issue #39723 requirements.
Out of Scope Changes check ✅ Passed All changes are in-scope frontend UI modifications for Recovery Lock password functionality. Minor supporting changes (e.g., endpoint helpers, activity types) are directly related to the core objective of implementing the password setting interface.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 39723-set-mac-recovery-lock-passwords-frontend

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 coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
frontend/pages/hosts/details/HostDetailsPage/HostActionsDropdown/helpers.tsx (1)

79-105: ⚠️ Potential issue | 🟠 Major

darwin is too broad for Recovery Lock.

The Passwords card already says this feature is only available on Apple silicon hosts, but this gate exposes the action on every macOS host. On unsupported Macs users will still see "Show Recovery Lock password" even though the flow can't succeed. Add a host capability flag to IHostActionConfigOptions and require it here before keeping the option.

Also applies to: 290-307

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/pages/hosts/details/HostDetailsPage/HostActionsDropdown/helpers.tsx`
around lines 79 - 105, Add a specific capability flag to the host action options
(e.g., add hostSupportsRecoveryLock: boolean to the IHostActionConfigOptions
interface) and use that flag in the decision that enables the "Show Recovery
Lock password" action (the gating logic that currently checks
isMacMdmEnabledAndConfigured / darwin mac checks). Update all places that
construct/consume IHostActionConfigOptions to supply hostSupportsRecoveryLock,
and change the condition that shows the Recovery Lock action to require
hostSupportsRecoveryLock === true in addition to any existing macOS checks so
the action only appears on Apple silicon hosts that support Recovery Lock.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/interfaces/host.ts`:
- Around line 115-130: The backend is missing a handler for the GET
/fleet/hosts/{id}/recovery_lock_password endpoint required by frontend
hostAPI.getRecoveryLockPassword and the IHostRecoveryLockPasswordResponse
contract; implement a new Go HTTP handler (and register its route) that accepts
host id, validates permissions, loads the host recovery lock entry, and returns
JSON shaped as { host_id: <id>, recovery_lock_password: { updated_at:
<timestamp>, password: <string|null> } } (use the same field names/types as the
frontend IHostRecoveryLockPasswordResponse), and ensure proper error responses
and tests cover missing host, unauthorized access, and empty password cases.

In
`@frontend/pages/hosts/details/HostDetailsPage/modals/RecoveryLockPasswordModal/_styles.scss`:
- Around line 2-3: The font-family declaration inside the .input-field rule uses
quoted "SourceCodePro" which Stylelint flags; update the .input-field
font-family to use an unquoted identifier (e.g., font-family: SourceCodePro,
$monospace;) so SourceCodePro is not wrapped in quotes while keeping the
fallback $monospace variable intact.

In
`@frontend/pages/hosts/details/HostDetailsPage/modals/RecoveryLockPasswordModal/RecoveryLockPasswordModal.tsx`:
- Around line 34-40: The RecoveryLockPasswordModal is caching the plaintext
password via the useQuery call (["hostRecoveryLockPassword", hostId] ->
hostAPI.getRecoveryLockPassword), so update that useQuery options to avoid
caching sensitive data by adding cacheTime: 0 and retry: false (e.g., merge into
the existing DEFAULT_USE_QUERY_OPTIONS) or alternatively ensure the query is
removed on modal close by calling
queryClient.removeQueries(["hostRecoveryLockPassword", hostId]) from the
cleanup/close handler; target the useQuery invocation in
RecoveryLockPasswordModal to apply the change.

In
`@frontend/pages/hosts/details/OSSettingsModal/OSSettingsTable/OSSettingsTableConfig.tsx`:
- Around line 166-173: The current early return in makeDarwinRows when profiles
is falsy causes valid synthetic macOS settings (e.g., recovery_lock_password
from os_settings) to be dropped; instead of returning null inside
makeDarwinRows, initialize an empty rows array when profiles is missing and
continue building rows so you can still push the synthetic entry based on
macos_settings or os_settings.recovery_lock_password; update the logic that
creates the synthetic row to check os_settings.recovery_lock_password and
macos_settings and append it to rows even if profiles is undefined, and return
rows (or null only if no rows were produced).

In `@frontend/pages/ManageControlsPage/OSSettings/cards/Passwords/Passwords.tsx`:
- Around line 54-82: The form allows submission before the team query succeeds
because enableRecoveryLockPassword is initialized to false and the useQuery call
(teamsAPI.load) doesn't handle errors; update the logic so the query explicitly
handles onError (e.g., set an error flag or surface a toast) and only considers
the team value valid when the query is successful (use isSuccess/isError from
useQuery); change enableRecoveryLockPassword's initial state to undefined (or a
nullable type) to represent "unknown", update the save handler to block
submission unless currentTeamId === API_NO_TEAM_ID or the query is not loading
and isSuccess is true, and update showLoading (or add showBlockedState) to
reflect isLoadingTeam || isError so the form is disabled until the team data is
successfully loaded; reference useQuery(["team", currentTeamId], ...),
onSuccess, onError, isLoadingTeam, isSuccess, enableRecoveryLockPassword,
setEnableRecoveryLockPassword, and showLoading when making these changes.

---

Outside diff comments:
In
`@frontend/pages/hosts/details/HostDetailsPage/HostActionsDropdown/helpers.tsx`:
- Around line 79-105: Add a specific capability flag to the host action options
(e.g., add hostSupportsRecoveryLock: boolean to the IHostActionConfigOptions
interface) and use that flag in the decision that enables the "Show Recovery
Lock password" action (the gating logic that currently checks
isMacMdmEnabledAndConfigured / darwin mac checks). Update all places that
construct/consume IHostActionConfigOptions to supply hostSupportsRecoveryLock,
and change the condition that shows the Recovery Lock action to require
hostSupportsRecoveryLock === true in addition to any existing macOS checks so
the action only appears on Apple silicon hosts that support Recovery Lock.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ac12d473-a8f7-4251-bcc1-db694c98bd4d

📥 Commits

Reviewing files that changed from the base of the PR and between 8642bc5 and 9cb2704.

📒 Files selected for processing (32)
  • frontend/__mocks__/configMock.ts
  • frontend/docs/patterns.md
  • frontend/interfaces/activity.ts
  • frontend/interfaces/config.ts
  • frontend/interfaces/host.ts
  • frontend/interfaces/mdm.ts
  • frontend/interfaces/team.ts
  • frontend/pages/DashboardPage/cards/ActivityFeed/GlobalActivityItem/GlobalActivityItem.tests.tsx
  • frontend/pages/DashboardPage/cards/ActivityFeed/GlobalActivityItem/GlobalActivityItem.tsx
  • frontend/pages/ManageControlsPage/OSSettings/OSSettings.tsx
  • frontend/pages/ManageControlsPage/OSSettings/OSSettingsNavItems.tsx
  • frontend/pages/ManageControlsPage/OSSettings/cards/Passwords/Passwords.tsx
  • frontend/pages/ManageControlsPage/OSSettings/cards/Passwords/_styles.scss
  • frontend/pages/ManageControlsPage/OSSettings/cards/Passwords/index.ts
  • frontend/pages/admin/components/SideNav/SideNav.tsx
  • frontend/pages/hosts/details/HostDetailsPage/HostActionsDropdown/HostActionsDropdown.tests.tsx
  • frontend/pages/hosts/details/HostDetailsPage/HostActionsDropdown/HostActionsDropdown.tsx
  • frontend/pages/hosts/details/HostDetailsPage/HostActionsDropdown/helpers.tsx
  • frontend/pages/hosts/details/HostDetailsPage/HostDetailsPage.tsx
  • frontend/pages/hosts/details/HostDetailsPage/modals/RecoveryLockPasswordModal/RecoveryLockPasswordModal.tsx
  • frontend/pages/hosts/details/HostDetailsPage/modals/RecoveryLockPasswordModal/_styles.scss
  • frontend/pages/hosts/details/HostDetailsPage/modals/RecoveryLockPasswordModal/index.ts
  • frontend/pages/hosts/details/OSSettingsModal/OSSettingsTable/OSSettingsTableConfig.tsx
  • frontend/pages/hosts/details/cards/Activity/ActivityConfig.tsx
  • frontend/pages/hosts/details/cards/Activity/ActivityItems/SetHostRecoveryLockPassword/SetHostRecoveryLockPassword.tsx
  • frontend/pages/hosts/details/cards/Activity/ActivityItems/SetHostRecoveryLockPassword/index.ts
  • frontend/pages/hosts/details/cards/Activity/ActivityItems/ViewedHostRecoveryLockPassword/ViewedHostRecoveryLockPassword.tsx
  • frontend/pages/hosts/details/cards/Activity/ActivityItems/ViewedHostRecoveryLockPassword/index.ts
  • frontend/pages/hosts/details/helpers.ts
  • frontend/router/paths.ts
  • frontend/services/entities/hosts.ts
  • frontend/utilities/endpoints.ts

Comment thread frontend/interfaces/host.ts Outdated
Comment thread frontend/pages/ManageControlsPage/OSSettings/cards/Passwords/Passwords.tsx Outdated
@jacobshandling jacobshandling changed the title UI: Set Mac recovery lock passwords UI: Set Mac Recovery Lock passwords Mar 6, 2026
@jacobshandling

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Mar 6, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
frontend/pages/hosts/details/OSSettingsModal/OSSettingsTable/OSSettingsTableConfig.tsx (1)

166-194: Inconsistent return behavior compared to other platform handlers.

makeWindowsRows and makeLinuxRows return null when there are no rows and no profiles (lines 133-134, 159-160), but makeDarwinRows now always returns an array (possibly empty). This inconsistency could affect callers that check for null to determine if data exists.

Consider adding the same guard at the end:

♻️ Suggested fix
   if (os_settings?.recovery_lock_password?.status) {
     rows = [
       ...rows,
       generateRecoveryLockPasswordSetting(
         os_settings.recovery_lock_password.status,
         os_settings.recovery_lock_password.detail
       ),
     ];
   }

+  if (rows.length === 0 && !profiles) {
+    return null;
+  }
+
   return rows;
 };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/pages/hosts/details/OSSettingsModal/OSSettingsTable/OSSettingsTableConfig.tsx`
around lines 166 - 194, makeDarwinRows currently always returns an array
(possibly empty) which is inconsistent with makeWindowsRows/makeLinuxRows that
return null when there are no rows; update makeDarwinRows (function name:
makeDarwinRows, variables: rows, profiles) to return null when rows is empty
(i.e., no profiles and no added settings) by adding a final guard that returns
rows if non-empty and null otherwise.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@frontend/pages/hosts/details/OSSettingsModal/OSSettingsTable/OSSettingsTableConfig.tsx`:
- Around line 166-194: makeDarwinRows currently always returns an array
(possibly empty) which is inconsistent with makeWindowsRows/makeLinuxRows that
return null when there are no rows; update makeDarwinRows (function name:
makeDarwinRows, variables: rows, profiles) to return null when rows is empty
(i.e., no profiles and no added settings) by adding a final guard that returns
rows if non-empty and null otherwise.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 15ee0a23-55bb-43fd-9058-b8758e1f6e4b

📥 Commits

Reviewing files that changed from the base of the PR and between 9cb2704 and 5cfc842.

📒 Files selected for processing (8)
  • frontend/interfaces/host.ts
  • frontend/pages/ManageControlsPage/OSSettings/cards/Passwords/Passwords.tsx
  • frontend/pages/hosts/details/HostDetailsPage/HostActionsDropdown/HostActionsDropdown.tsx
  • frontend/pages/hosts/details/HostDetailsPage/HostActionsDropdown/helpers.tsx
  • frontend/pages/hosts/details/HostDetailsPage/HostDetailsPage.tsx
  • frontend/pages/hosts/details/HostDetailsPage/modals/RecoveryLockPasswordModal/RecoveryLockPasswordModal.tsx
  • frontend/pages/hosts/details/HostDetailsPage/modals/RecoveryLockPasswordModal/_styles.scss
  • frontend/pages/hosts/details/OSSettingsModal/OSSettingsTable/OSSettingsTableConfig.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • frontend/pages/hosts/details/HostDetailsPage/modals/RecoveryLockPasswordModal/_styles.scss
  • frontend/interfaces/host.ts
  • frontend/pages/hosts/details/HostDetailsPage/modals/RecoveryLockPasswordModal/RecoveryLockPasswordModal.tsx

@getvictor

Copy link
Copy Markdown
Member

This is a big PR. I'm starting to look at it now.

@getvictor getvictor left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Thank you.

Comment thread frontend/docs/patterns.md
Comment on lines +519 to +520
If you are dealing with a page that *updates* any kind of config, set the local
config with the response of your update call to make sure it has the latest.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Comment thread frontend/interfaces/host.ts
<Button
disabled={isFormDisabled || gitopsDisabled}
className={`${baseClass}__save-button`}
onClick={onUpdateRecoveryLockPassword}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a pattern when to have loading state on save and when not to?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generally we should

@jacobshandling
jacobshandling merged commit 46f8cf4 into main Mar 10, 2026
20 checks passed
@jacobshandling
jacobshandling deleted the 39723-set-mac-recovery-lock-passwords-frontend branch March 10, 2026 17:05
@jacobshandling
jacobshandling restored the 39723-set-mac-recovery-lock-passwords-frontend branch March 10, 2026 18:12
@jacobshandling
jacobshandling deleted the 39723-set-mac-recovery-lock-passwords-frontend branch March 10, 2026 18:17
@coderabbitai coderabbitai Bot mentioned this pull request Apr 8, 2026
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Set passwords: FE

2 participants