Skip to content

[PM-33981] feat: Integrate device management into Account Security#2491

Draft
andrebispo5 wants to merge 1 commit intopm-33981/innovation-device-listfrom
pm-33981/account-security-integration
Draft

[PM-33981] feat: Integrate device management into Account Security#2491
andrebispo5 wants to merge 1 commit intopm-33981/innovation-device-listfrom
pm-33981/account-security-integration

Conversation

@andrebispo5
Copy link
Copy Markdown
Contributor

@andrebispo5 andrebispo5 commented Mar 25, 2026

Depends on: #2490

🎟️ Tracking

https://bitwarden.atlassian.net/browse/PM-33981

📔 Objective

Integrate the device management feature into Account Security settings:

  • Add deviceManagement route to SettingsRoute
  • Add navigation handling in SettingsCoordinator
  • Add isManageDevicesEnabled state and manageDevicesTapped action
  • Add "Manage devices" menu item in Account Security Other section
  • Hide legacy "Approve login requests" when device management is enabled
  • Reorder Other section: Manage devices → Two-step login → Fingerprint phrase

@andrebispo5 andrebispo5 requested review from a team and matt-livefront as code owners March 25, 2026 17:22
Copilot AI review requested due to automatic review settings March 25, 2026 17:22
@github-actions github-actions bot added app:password-manager Bitwarden Password Manager app context t:feature labels Mar 25, 2026
@andrebispo5 andrebispo5 marked this pull request as draft March 25, 2026 17:26
@github-actions
Copy link
Copy Markdown
Contributor

Logo
Checkmarx One – Scan Summary & Detailsc84013c9-d446-4ddb-8733-77a5ba26d079

Great job! No new security vulnerabilities introduced in this pull request

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Integrates “device management” entry points into the Settings → Account Security area by adding a new route, navigation handling, and UI/state gating behind a feature flag.

Changes:

  • Added deviceManagement to SettingsRoute and wired navigation in SettingsCoordinator.
  • Added isManageDevicesEnabled state + manageDevicesTapped action, and updated Account Security UI to show “Manage devices” (and hide legacy pending login requests) when enabled.
  • Reordered items in the Account Security “Other” section.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
BitwardenShared/UI/Platform/Settings/SettingsRoute.swift Adds deviceManagement route.
BitwardenShared/UI/Platform/Settings/SettingsCoordinator.swift Handles .deviceManagement navigation and attempts to present a device management screen.
BitwardenShared/UI/Platform/Settings/Settings/AccountSecurity/AccountSecurityView.swift Adds “Manage devices” row (flagged) and hides pending login requests when enabled.
BitwardenShared/UI/Platform/Settings/Settings/AccountSecurity/AccountSecurityState.swift Adds isManageDevicesEnabled state flag.
BitwardenShared/UI/Platform/Settings/Settings/AccountSecurity/AccountSecurityProcessor.swift Loads feature flag and routes .manageDevicesTapped to .deviceManagement.
BitwardenShared/UI/Platform/Settings/Settings/AccountSecurity/AccountSecurityAction.swift Adds .manageDevicesTapped action.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


state.isAuthenticatorSyncEnabled = try await services.stateService.getSyncToAuthenticator()

state.isManageDevicesEnabled = await services.configService.getFeatureFlag(.manageDevices)
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

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

FeatureFlag.manageDevices is not defined (the FeatureFlag extension only defines flags like .deviceAuthKey, .cxpExportMobile, etc.), so this won’t compile. Add a static let manageDevices = FeatureFlag(rawValue: ...) and include it in FeatureFlag.allCases (this codebase uses a manually maintained allCases).

Copilot uses AI. Check for mistakes.
Comment on lines +102 to 104
case .manageDevicesTapped:
coordinator.navigate(to: .deviceManagement)
case .pendingLoginRequestsTapped:
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

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

New behavior isn’t covered by tests: there’s no test asserting .manageDevicesTapped navigates to .deviceManagement, and no test that loadData() sets isManageDevicesEnabled based on the feature flag (no manageDevices references in AccountSecurityProcessorTests). Please add coverage for both.

Copilot uses AI. Check for mistakes.
await store.perform(.accountFingerprintPhrasePressed)
if store.state.isManageDevicesEnabled {
SettingsListItem(
Localizations.manageDevices,
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

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

Localizations.manageDevices doesn’t appear to be backed by a localization key in en.lproj/Localizable.strings (no "ManageDevices" entry). This will break SwiftGen generation / compilation. Please add the ManageDevices string key (and regenerate if needed) before referencing it here.

Suggested change
Localizations.manageDevices,
"Manage devices",

Copilot uses AI. Check for mistakes.
Comment on lines +24 to +26
if !store.state.isManageDevicesEnabled {
pendingLoginRequests
}
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

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

The new conditional UI paths aren’t covered by AccountSecurityView ViewInspector tests: when isManageDevicesEnabled == true, the pending login requests section should be hidden and the “Manage devices” row should appear and dispatch .manageDevicesTapped on tap. Please add tests for these cases.

Copilot uses AI. Check for mistakes.
Comment on lines +354 to +359
let processor = DeviceManagementProcessor(
coordinator: asAnyCoordinator(),
services: services,
state: DeviceManagementState(),
)
stackNavigator?.present(DeviceManagementView(store: Store(processor: processor)))
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

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

DeviceManagementProcessor/DeviceManagementState/DeviceManagementView don’t exist anywhere in the repo (search for these symbols only finds this usage), so this route won’t compile. Please add the device management screen implementation (or import the correct module) before wiring up navigation here.

Suggested change
let processor = DeviceManagementProcessor(
coordinator: asAnyCoordinator(),
services: services,
state: DeviceManagementState(),
)
stackNavigator?.present(DeviceManagementView(store: Store(processor: processor)))
// TODO: Implement device management flow and present the appropriate view.
// Currently left as a no-op to avoid referencing undefined types.
assertionFailure("Device management screen is not yet implemented.")

Copilot uses AI. Check for mistakes.
Comment on lines 171 to +173
showDeleteAccount()
case .deviceManagement:
showDeviceManagement()
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

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

There’s no regression test coverage for the new .deviceManagement route in SettingsCoordinatorTests (no references to deviceManagement there). Please add a test that navigating to .deviceManagement presents/pushes the expected device management screen.

Copilot uses AI. Check for mistakes.
@andrebispo5 andrebispo5 added the innovation Feature work related to Innovation Sprint or BEEEP projects label Mar 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app:password-manager Bitwarden Password Manager app context innovation Feature work related to Innovation Sprint or BEEEP projects t:feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants