1
0
mirror of https://github.com/bitwarden/browser synced 2026-01-22 12:23:46 +00:00

exclude deleted items from at risk check (#18246)

This commit is contained in:
Nick Krantz
2026-01-08 11:33:24 -06:00
committed by GitHub
parent 4866eaa2ec
commit de2ebc484a
2 changed files with 69 additions and 2 deletions

View File

@@ -250,6 +250,38 @@ describe("DefaultCipherRiskService", () => {
expect.any(Object),
);
});
it("should filter out deleted Login ciphers", async () => {
const mockClient = sdkService.simulate.userLogin(mockUserId);
const mockCipherRiskClient = mockClient.vault.mockDeep().cipher_risk.mockDeep();
mockCipherRiskClient.compute_risk.mockResolvedValue([]);
const activeCipher = new CipherView();
activeCipher.id = mockCipherId1;
activeCipher.type = CipherType.Login;
activeCipher.login = new LoginView();
activeCipher.login.password = "password1";
activeCipher.deletedDate = undefined;
const deletedCipher = new CipherView();
deletedCipher.id = mockCipherId2;
deletedCipher.type = CipherType.Login;
deletedCipher.login = new LoginView();
deletedCipher.login.password = "password2";
deletedCipher.deletedDate = new Date();
await cipherRiskService.computeRiskForCiphers([activeCipher, deletedCipher], mockUserId);
expect(mockCipherRiskClient.compute_risk).toHaveBeenCalledWith(
[
expect.objectContaining({
id: expect.anything(),
password: "password1",
}),
],
expect.any(Object),
);
});
});
describe("buildPasswordReuseMap", () => {
@@ -284,6 +316,41 @@ describe("DefaultCipherRiskService", () => {
]);
expect(result).toEqual(mockReuseMap);
});
it("should exclude deleted ciphers when building password reuse map", async () => {
const mockClient = sdkService.simulate.userLogin(mockUserId);
const mockCipherRiskClient = mockClient.vault.mockDeep().cipher_risk.mockDeep();
const mockReuseMap = {
password1: 1,
};
mockCipherRiskClient.password_reuse_map.mockReturnValue(mockReuseMap);
const activeCipher = new CipherView();
activeCipher.id = mockCipherId1;
activeCipher.type = CipherType.Login;
activeCipher.login = new LoginView();
activeCipher.login.password = "password1";
activeCipher.deletedDate = undefined;
const deletedCipherWithSamePassword = new CipherView();
deletedCipherWithSamePassword.id = mockCipherId2;
deletedCipherWithSamePassword.type = CipherType.Login;
deletedCipherWithSamePassword.login = new LoginView();
deletedCipherWithSamePassword.login.password = "password1";
deletedCipherWithSamePassword.deletedDate = new Date();
const result = await cipherRiskService.buildPasswordReuseMap(
[activeCipher, deletedCipherWithSamePassword],
mockUserId,
);
expect(mockCipherRiskClient.password_reuse_map).toHaveBeenCalledWith([
expect.objectContaining({ password: "password1" }),
]);
expect(result).toEqual(mockReuseMap);
});
});
describe("computeCipherRiskForUser", () => {

View File

@@ -71,7 +71,6 @@ export class DefaultCipherRiskService implements CipherRiskServiceAbstraction {
passwordMap,
checkExposed,
});
return results[0];
}
@@ -103,7 +102,8 @@ export class DefaultCipherRiskService implements CipherRiskServiceAbstraction {
return (
cipher.type === CipherType.Login &&
cipher.login?.password != null &&
cipher.login.password !== ""
cipher.login.password !== "" &&
!cipher.isDeleted
);
})
.map(