1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-12 14:23:32 +00:00

[PM-21041] Fix cipher view security tasks fetching (#14569)

* [PM-21041] Add taskEnabled$ dependency to tasks$ observable

* [PM-21041] Rework cipher view component to only check tasks for organization Login type ciphers

- Remove dependency on feature flag check (handled by tasks$ observable now)
- Add try/catch in case of request failures to avoid breaking component initialization

* [PM-21041] Remove now redundant taskEnabled$ chain

* [PM-21041] Fix tests
This commit is contained in:
Shane Melton
2025-05-01 11:22:32 -07:00
committed by GitHub
parent de6b58c10a
commit cba5f826d6
6 changed files with 147 additions and 73 deletions

View File

@@ -1,7 +1,7 @@
import { CommonModule } from "@angular/common";
import { Component, inject } from "@angular/core";
import { RouterModule } from "@angular/router";
import { map, of, switchMap } from "rxjs";
import { map, switchMap } from "rxjs";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { getUserId } from "@bitwarden/common/auth/services/account.service";
@@ -20,21 +20,7 @@ export class AtRiskPasswordCalloutComponent {
private activeAccount$ = inject(AccountService).activeAccount$.pipe(getUserId);
protected pendingTasks$ = this.activeAccount$.pipe(
switchMap((userId) =>
this.taskService.tasksEnabled$(userId).pipe(
switchMap((enabled) => {
if (!enabled) {
return of([]);
}
return this.taskService
.pendingTasks$(userId)
.pipe(
map((tasks) =>
tasks.filter((t) => t.type === SecurityTaskType.UpdateAtRiskCredential),
),
);
}),
),
),
switchMap((userId) => this.taskService.pendingTasks$(userId)),
map((tasks) => tasks.filter((t) => t.type === SecurityTaskType.UpdateAtRiskCredential)),
);
}

View File

@@ -8,14 +8,16 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { Utils } from "@bitwarden/common/platform/misc/utils";
import { FakeAccountService, mockAccountServiceWith } from "@bitwarden/common/spec";
import { UserId } from "@bitwarden/common/types/guid";
import { UserId, EmergencyAccessId } from "@bitwarden/common/types/guid";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
import { CipherType } from "@bitwarden/common/vault/enums";
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
import { LoginView } from "@bitwarden/common/vault/models/view/login.view";
import { TaskService } from "@bitwarden/common/vault/tasks";
import { DialogService, DialogRef, DIALOG_DATA } from "@bitwarden/components";
import { ChangeLoginPasswordService } from "@bitwarden/vault";
@@ -28,14 +30,15 @@ describe("EmergencyViewDialogComponent", () => {
const open = jest.fn();
const close = jest.fn();
const emergencyAccessId = "emergency-access-id" as EmergencyAccessId;
const mockCipher = {
id: "cipher1",
name: "Cipher",
type: CipherType.Login,
login: { uris: [] },
login: { uris: [] } as Partial<LoginView>,
card: {},
} as CipherView;
} as Partial<CipherView> as CipherView;
const accountService: FakeAccountService = mockAccountServiceWith(Utils.newGuid() as UserId);
@@ -56,6 +59,7 @@ describe("EmergencyViewDialogComponent", () => {
{ provide: DIALOG_DATA, useValue: { cipher: mockCipher } },
{ provide: AccountService, useValue: accountService },
{ provide: TaskService, useValue: mock<TaskService>() },
{ provide: LogService, useValue: mock<LogService>() },
],
})
.overrideComponent(EmergencyViewDialogComponent, {
@@ -94,18 +98,24 @@ describe("EmergencyViewDialogComponent", () => {
});
it("opens dialog", () => {
EmergencyViewDialogComponent.open({ open } as unknown as DialogService, { cipher: mockCipher });
EmergencyViewDialogComponent.open({ open } as unknown as DialogService, {
cipher: mockCipher,
emergencyAccessId,
});
expect(open).toHaveBeenCalled();
});
it("closes the dialog", () => {
EmergencyViewDialogComponent.open({ open } as unknown as DialogService, { cipher: mockCipher });
EmergencyViewDialogComponent.open({ open } as unknown as DialogService, {
cipher: mockCipher,
emergencyAccessId,
});
fixture.detectChanges();
const cancelButton = fixture.debugElement.queryAll(By.css("button")).pop();
cancelButton.nativeElement.click();
cancelButton!.nativeElement.click();
expect(close).toHaveBeenCalled();
});