* feat(dirt): add newApplications$ observable to orchestrator Add reactive observable that filters applicationData for unreviewed apps (reviewedDate === null). Observable automatically updates when report state changes through the pipeline. - Add newApplications$ observable with distinctUntilChanged - Filters rawReportData$.data.applicationData - Uses shareReplay for multi-subscriber efficiency Related to PM-27284 * feat(dirt): add saveApplicationReviewStatus$ to orchestrator Implement method to save application review status and critical flags. Updates all applications where reviewedDate === null to set current date, and marks selected applications as critical. - Add saveApplicationReviewStatus$() method - Add _updateReviewStatusAndCriticalFlags() helper - Uses existing encryption and API update patterns - Single API call for both review status and critical flags - Follows same pattern as saveCriticalApplications$() Related to PM-27284 * feat(dirt): expose newApplications$ in data service Expose orchestrator's newApplications$ observable and save method through RiskInsightsDataService facade. Maintains clean separation between orchestrator (business logic) and components (UI). - Expose newApplications$ observable - Expose saveApplicationReviewStatus() delegation method - Maintains facade pattern consistency Related to PM-27284 * feat(dirt): make AllActivitiesService reactive to new applications Update AllActivitiesService to subscribe to orchestrator's newApplications$ observable instead of receiving data through summary updates. - Subscribe to dataService.newApplications$ in constructor - Add setNewApplications() helper method - Remove newApplications update from setAllAppsReportSummary() - New applications now update reactively when review status changes Related to PM-27284 * feat(dirt): connect dialog to review status save method Update NewApplicationsDialogComponent to call the data service's saveApplicationReviewStatus method when marking applications as critical. - Inject RiskInsightsDataService - Replace placeholder onMarkAsCritical() with real implementation - Handle success/error cases with appropriate toast notifications - Close dialog on successful save - Show different messages based on whether apps were marked critical Related to PM-27284 * feat(dirt): add i18n strings for application review Add internationalization strings for the new applications review dialog success and error messages. - applicationReviewSaved: Success toast title - applicationsMarkedAsCritical: Success message when apps marked critical - newApplicationsReviewed: Success message when apps reviewed only - errorSavingReviewStatus: Error toast title - pleaseTryAgain: Error toast message Related to PM-27284 * fix(dirt): add subscription cleanup to AllActivitiesService Critical fix for production code quality and memory leak prevention. Adds takeUntil pattern to all subscriptions to comply with ADR-0003 (Observable Data Services) requirements. **Subscription Cleanup (ADR-0003 Compliance):** - Add takeUntil pattern to AllActivitiesService subscriptions - Add _destroy$ Subject and destroy() method - Prevents memory leaks by properly unsubscribing from observables - Follows Observable Data Services ADR requirements Changes: - Import Subject and takeUntil from rxjs - Add private _destroy$ Subject for cleanup coordination - Apply takeUntil(this._destroy$) to all 3 subscriptions: - enrichedReportData$ subscription - criticalReportResults$ subscription - newApplications$ subscription - Add destroy() method for proper resource cleanup This ensures proper resource cleanup and follows Bitwarden's architectural decision records for observable management. Related to PM-27284 * fix(dirt): replace manual takeUntil with takeUntilDestroyed in AllActivitiesService Fixes critical memory leak by replacing manual subscription cleanup with Angular's automatic DestroyRef-based cleanup pattern. **Changes:** - Replace `takeUntil(this._destroy$)` with `takeUntilDestroyed()` for all 3 subscriptions - Remove unused `_destroy$` Subject and manual `destroy()` method - Update imports to use `@angular/core/rxjs-interop` **Why:** - Manual `destroy()` method was never called anywhere in codebase - Subscriptions accumulated without cleanup, causing memory leaks - `takeUntilDestroyed()` uses Angular's DestroyRef for automatic cleanup - Aligns with ADR-0003 and .claude/CLAUDE.md requirements **Impact:** - Automatic subscription cleanup when service context is destroyed - Prevents memory leaks during hot module reloads and route changes - Reduces code complexity (no manual lifecycle management needed) Related to PM-27284 * refactor(dirt): remove newApplications from OrganizationReportSummary Removes redundant newApplications field from summary type and uses derived newApplications$ observable from orchestrator instead. **Changes:** - Remove newApplications from OrganizationReportSummary type definition - Remove dummy data array from RiskInsightsReportService.getApplicationsSummary() - Remove newApplications subscription from AllActivitiesService - Update AllActivityComponent to subscribe directly to dataService.newApplications$ **Why:** - Eliminates data redundancy (stored vs derived) - newApplications$ already computes from applicationData.reviewedDate === null - Single source of truth: applicationData is the source - Simplifies encrypted payload (less data in summary) - Better separation: stored data (counts) vs computed data (lists) **Impact:** - No functional changes - UI continues to display new applications correctly - Cleaner architecture with computed observable pattern * cleanup * fix(dirt): improve dialog type safety and error logging Addresses critical PR review issues in NewApplicationsDialogComponent: **Type Safety:** - Replace unsafe type casting `(this as any).dialogRef` with proper DialogRef injection - Inject DialogRef<boolean | undefined> using Angular's inject() function - Ensures type safety and prevents runtime errors from missing dialogRef **Error Handling:** - Add LogService to dialog component - Log errors with "[NewApplicationsDialog]" for debugging - Maintain user-facing error toast while adding server-side logging **Impact:** - Eliminates TypeScript safety bypasses - Improves production debugging capabilities - Follows Angular dependency injection best practices * fixing mock data and test cases for new apps * feat(dirt): create assign tasks view component Create standalone view component for task assignment UI that can be embedded within dialogs or other containers. - Add AssignTasksViewComponent with signal-based inputs/outputs - Use input.required<number>() for selectedApplicationsCount - Use output<void>() for tasksAssigned and back events - Implement task calculation using SecurityTasksApiService - Add onAssignTasks() method with loading state and error handling - Include task summary card UI matching password-change-metric style - Add proper subscription cleanup with takeUntilDestroyed (ADR-0003) - Buttons included in component template (not dialog footer) - Component retrieves organizationId from route params Related to PM-27619 * refactor(dirt): add multi-view state management to new applications dialog Add view state const object and properties to support toggling between application selection and embedded assign tasks component. - Add DialogView const object with SelectApplications and AssignTasks states (ADR-0025) - Add DialogView type for type safety - Add currentView property to track active view - Import AssignTasksViewComponent for embedded use - Add isCalculatingTasks loading state - Inject AllActivitiesService and SecurityTasksApiService for task checking - Implement OnInit with organizationId retrieval from route params - Add proper subscription cleanup with takeUntilDestroyed (ADR-0003) - Expose DialogView constants to template Related to PM-27619 * feat(dirt): integrate assign tasks view into dialog Implement logic to embed AssignTasksViewComponent within dialog and handle communication via event bindings. - Update onMarkAsCritical to check for tasks before closing dialog - Add checkForTasksToAssign() method using SecurityTasksApiService - Conditionally transition to AssignTasks view when tasks are available - Add onTasksAssigned() handler to close dialog after successful assignment - Add onBack() handler to navigate back to SelectApplications view - Add loading state guard to prevent double-click on Mark as Critical button - Only show success toast and close dialog if no tasks to assign Related to PM-27619 * feat(dirt): add embedded assign tasks view to dialog template Update dialog template to conditionally render embedded AssignTasksViewComponent using @if directive. - Add conditional rendering for SelectApplications and AssignTasks views - Update dialog title dynamically based on currentView - Embed dirt-assign-tasks-view component in AssignTasks view - Pass selectedApplicationsCount via input binding - Listen to tasksAssigned and back output events - Show footer buttons only for SelectApplications view - Add loading and disabled states to Mark as Critical button - Change Cancel button to not auto-close (user must navigate) Related to PM-27619 * feat(dirt): add i18n keys for assign tasks view Add localized strings for embedded assign tasks view component. * resolve organizationId and DI issues in assign tasks flow - Pass organizationId via dialog data to prevent async race conditions - Pass organizationId as input to AssignTasksViewComponent (embedded components can't access route params) - Add DefaultAdminTaskService to component providers to fix NullInjectorError - Remove unnecessary route subscription from embedded component - Follow password-change-metric.component.ts pattern for consistency - Add detailed comments explaining architectural decisions and bug fixes * cleanup styling * refactor(dirt): remove newApplications validation from OrganizationReportSummary type guard Removes redundant newApplications field validation from the OrganizationReportSummary type guard and related test cases. **Changes:** - Remove "newApplications" from allowed keys in isOrganizationReportSummary() - Remove newApplications array validation logic - Remove newApplications validation from validateOrganizationReportSummary() - Remove 2 test cases for newApplications validation - Remove newApplications field from 8 test data objects **Rationale:** The newApplications field was removed from OrganizationReportSummary type definition because it's derived data that can be calculated from applicationData (filtering where reviewedDate === null). The data is now accessed via the reactive newApplications$ observable instead of being stored redundantly in the summary object. **Impact:** - No functional changes - UI continues to display new applications via observable - Type guard now correctly validates the actual OrganizationReportSummary structure - Eliminates data redundancy and maintains single source of truth - All 43 tests passing * improve assign tasks view display - Remove illustration/preview section (mailbox icon and prompt text) - Show unique member count instead of calculated task count - Use reportSummary.totalCriticalAtRiskMemberCount from AllActivitiesService - Remove unused SecurityTasksApiService dependency - Follow same pattern as all-activity.component.ts for consistency * logic to fetch totals and new styling * Fix review applications review view and assign view flow * Fix null type checks * refactor assign tasks dialog: use callout component, add video, fix OnPush, improve error handling * Add columns, description, search, and bulk select to new applications dialog * Add count placeholder for critical applications marked message * Address claude comments --------- Co-authored-by: Tom <ttalty@bitwarden.com> Co-authored-by: Leslie Tilton <23057410+Banrion@users.noreply.github.com> Co-authored-by: maxkpower <mpower@bitwarden.com>
Bitwarden Client Applications
This repository houses all Bitwarden client applications except the mobile applications (iOS | android).
Please refer to the Clients section of the Contributing Documentation for build instructions, recommended tooling, code style tips, and lots of other great information to get you started.
Related projects:
- bitwarden/server: The core infrastructure backend (API, database, Docker, etc).
- bitwarden/ios: Bitwarden iOS Password Manager & Authenticator apps.
- bitwarden/android: Bitwarden Android Password Manager & Authenticator apps.
- bitwarden/directory-connector: A tool for syncing a directory (AD, LDAP, Azure, G Suite, Okta) to an organization.
We're Hiring!
Interested in contributing in a big way? Consider joining our team! We're hiring for many positions. Please take a look at our Careers page to see what opportunities are currently open as well as what it's like to work at Bitwarden.
Contribute
Code contributions are welcome! Please commit any pull requests against the main branch. Learn more about how to contribute by reading the Contributing Guidelines. Check out the Contributing Documentation for how to get started with your first contribution.
Security audits and feedback are welcome. Please open an issue or email us privately if the report is sensitive in nature. You can read our security policy in the SECURITY.md file.
