* enforce session timeout policy
* better angular validation
* lint fix
* missing switch break
* fallback when timeout not supported with highest available timeout
* failing unit tests
* incorrect policy message
* vault timeout type adjustments
* fallback to "on browser refresh" for browser, when policy is set to "on system locked", but not available (Safari)
* docs, naming improvements
* fallback for current user session timeout to "on refresh", when policy is set to "on system locked", but not available.
* don't display policy message when the policy does not affect available timeout options
* 8 hours default when changing from non-numeric timeout to Custom.
* failing unit test
* missing locales, changing functions access to private, docs
* removal of redundant magic number
* missing await
* await once for available timeout options
* adjusted messaging
* unit test coverage
* vault timeout numeric module exports
* unit test coverage
* Access Intelligence display for only enterprise
* modifying the access intelligence routing to properly match. Added documentation.
* tasks remove useriskinsights flag
* fixing tasks test cases
* tasks should only check for enterprise
* fixing uncommitted changes
* reverting unecessary change from all activites
* adding back missing test case
* Fix icons in application review table
* Add default icon if none is found in review applications table. Move function to computed signal
* Rename function
* Remove redundant if statement
* Added function to get a cipher icon for application tables. Update all application component to use signal properties
* Fix type
* Handle no ciphers on application
* Fix reviews not saving in new applications review. Skip assign page if no at risk passwords are to be assigned. Fix bug in password change widget
* Claude comment improvements
* PM-23810 fixing ux issue for member access report export csv
* PM-23810 merged in new KM changes and filter nulls within the collectionName array
* PM-23810 fixing type error
* PM-23810 removing unit test as it was based on a previous solution.
* feat(dirt): add "needs review" state for applications needing initial review
- Add showNeedsReviewState to display warning when all apps lack review dates
- Track noAppsHaveReviewDate flag to identify unreviewed applications
- Add i18n strings for organization items count and review prompt
- Update activity card to show 3 states: all caught up, needs review, new apps
- Apply tw-col-span-2 to needs review card for better visibility
* refactor: split activity card states into separate @if blocks for readability
* fix: set hasLoadedApplicationData when summary data arrives
Previously, hasLoadedApplicationData was only set in the enrichedReportData$
subscription, which fired after reportSummary$ and newApplications$. This
caused a timing issue where showNeedsReviewState would remain false even when
newApplicationsCount === totalApplicationCount because the flag wasn't set yet.
Now we set hasLoadedApplicationData=true as soon as reportSummary$ arrives
with totalApplicationCount > 0, ensuring proper synchronization.
---------
Co-authored-by: Tom <ttalty@bitwarden.com>
* Update type guard for cipher ids on reports
* Update report model cipher id type and mock data
* Update security tasks api service to have copied getAllTasks function from the vault team
* Expose critical application at risk cipher ids
* Update cipher id type in report service. Update all activities service to move task function to task service
* Update module
* Update organization id sharing through components instead of multiple route fetchings
* Update view type of password change widget. Update variables to be signals. Refactor logic for calculations based on individual tasks
* Update usage of request password change function
* Update security tasks service to manage tasks
* Remove unused variable
* Alphabetized functions, added documentation. Removed injectable decorator
* Alphabetize constructor params for password health service
* Update providers
* Address NaN case on percentage. Address obsolete type casting to CipherID and any other claude comments
* Fix dependency array in test case
- Show "Prioritize critical applications" when org has no critical apps
- Show "Review new applications" when org already has critical apps
- Add hasExistingCriticalApplications flag to dialog data
- Add reviewNewApplications i18n keys
* 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>
* add "All caught up!" state for application review card
- Display success state when all applications have been reviewed and no new applications need review
- Add iconColorClass input to activity-card component to support conditional icon colors (green checkmark for success state)
- Add i18n keys: allCaughtUp and noNewApplicationsToReviewAtThisTime
- Check if all apps have review dates via enrichedReportData$ to determine when to show the caught up state
* fix "Potential Race Condition with State Initialization" from claude issue and replace getter
* Consolidate loading state and handle null report from api response
* Fix jumping of page when ciphers are still loading
* Fix type errors
* Fix loading state
* Update type guards
* Add metric data types. Update places saving a risk insights report summary to save metrics
* Fix types and test error
* Fix critical report members
* Update test case for null username in type-guard
* Fix report application mapped data check
* max init
* add mp4 and organize code better
* fix lint errors
* move empty state logic into risk insights component
* replace getter logic
* sub for org name
* checkForVaultItems fix
- need to use cipherservice instead of report results from data service
* fix all critical issues mentioned by claude bot
* resolve empty state logic bug and memory leaks
- Handle zero-results case in empty state logic
- Add takeUntil cleanup to _setupUserId subscription
- Guard console.warn with isDevMode() check
* use tuple arrays for benefits to prevent XSS risk
Replace pipe-separated strings with typed tuple arrays [string, string][]
for benefits data in empty state component. This eliminates potential XSS
risk from string splitting, provides compile-time type safety, and improves
performance by removing runtime string parsing on every change detection.
* fix(dirt): hide empty states during report generation and fix memory leak
Add isGeneratingReport$ to combineLatest, update empty state conditions
to check !isGenerating, simplify run report logic, and fix memory leak
in route.queryParams subscription.
Addresses Claude bot feedback on PR #16832
* refactor(dirt): use signals and OnPush in empty state card component
Convert @Input() to readonly input signals and add OnPush change
detection strategy. Update template to call signals as functions.
Fixes ESLint compliance issues.
* refactor(dirt): remove unused shouldShowRunReportState variable
The shouldShowRunReportState variable was calculated but never used.
The template already uses @else for the run report state, making this
variable redundant.
* refactor(dirt): consolidate duplicate if statements in empty state logic
Merge 5 separate if/else blocks checking shouldShowImportDataState into
single consolidated block. Move constant benefits assignment outside
conditional. Improves readability and reduces duplication.
* remove unnecessary getOrganizationName wrapper method
* remove duplicate runReport method
Remove runReport arrow function and use generateReport consistently.
Both methods called dataService.triggerReport(), but generateReport
includes an organizationId check for defensive programming.
* 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
* 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
---------
Co-authored-by: Tom <ttalty@bitwarden.com>