mirror of
https://github.com/bitwarden/browser
synced 2025-12-06 00:13:28 +00:00
[PM-17577] Inactive two-step login report - check hostname and domain name (#16823)
This commit is contained in:
@@ -121,4 +121,153 @@ describe("InactiveTwoFactorReportComponent", () => {
|
||||
it("should call fullSync method of syncService", () => {
|
||||
expect(syncServiceMock.fullSync).toHaveBeenCalledWith(false);
|
||||
});
|
||||
|
||||
describe("isInactive2faCipher", () => {
|
||||
beforeEach(() => {
|
||||
// Add both domain and host to services map
|
||||
component.services.set("example.com", "https://example.com/2fa-doc");
|
||||
component.services.set("sub.example.com", "https://sub.example.com/2fa-doc");
|
||||
fixture.detectChanges();
|
||||
});
|
||||
it("should return true and documentation for cipher with matching domain", () => {
|
||||
const cipher = createCipherView({
|
||||
login: {
|
||||
uris: [{ uri: "https://example.com/login" }],
|
||||
},
|
||||
});
|
||||
const [doc, isInactive] = (component as any).isInactive2faCipher(cipher);
|
||||
expect(isInactive).toBe(true);
|
||||
expect(doc).toBe("https://example.com/2fa-doc");
|
||||
});
|
||||
|
||||
it("should return true and documentation for cipher with matching host", () => {
|
||||
const cipher = createCipherView({
|
||||
login: {
|
||||
uris: [{ uri: "https://sub.example.com/login" }],
|
||||
},
|
||||
});
|
||||
const [doc, isInactive] = (component as any).isInactive2faCipher(cipher);
|
||||
expect(isInactive).toBe(true);
|
||||
expect(doc).toBe("https://sub.example.com/2fa-doc");
|
||||
});
|
||||
|
||||
it("should return false for cipher with non-matching domain or host", () => {
|
||||
const cipher = createCipherView({
|
||||
login: {
|
||||
uris: [{ uri: "https://otherdomain.com/login" }],
|
||||
},
|
||||
});
|
||||
const [doc, isInactive] = (component as any).isInactive2faCipher(cipher);
|
||||
expect(isInactive).toBe(false);
|
||||
expect(doc).toBe("");
|
||||
});
|
||||
|
||||
it("should return false if cipher type is not Login", () => {
|
||||
const cipher = createCipherView({
|
||||
type: 2,
|
||||
login: {
|
||||
uris: [{ uri: "https://example.com/login" }],
|
||||
},
|
||||
});
|
||||
const [doc, isInactive] = (component as any).isInactive2faCipher(cipher);
|
||||
expect(isInactive).toBe(false);
|
||||
expect(doc).toBe("");
|
||||
});
|
||||
|
||||
it("should return false if cipher has TOTP", () => {
|
||||
const cipher = createCipherView({
|
||||
login: {
|
||||
totp: "some-totp",
|
||||
uris: [{ uri: "https://example.com/login" }],
|
||||
},
|
||||
});
|
||||
const [doc, isInactive] = (component as any).isInactive2faCipher(cipher);
|
||||
expect(isInactive).toBe(false);
|
||||
expect(doc).toBe("");
|
||||
});
|
||||
|
||||
it("should return false if cipher is deleted", () => {
|
||||
const cipher = createCipherView({
|
||||
isDeleted: true,
|
||||
login: {
|
||||
uris: [{ uri: "https://example.com/login" }],
|
||||
},
|
||||
});
|
||||
const [doc, isInactive] = (component as any).isInactive2faCipher(cipher);
|
||||
expect(isInactive).toBe(false);
|
||||
expect(doc).toBe("");
|
||||
});
|
||||
|
||||
it("should return false if cipher does not have edit access and no organization", () => {
|
||||
component.organization = null;
|
||||
const cipher = createCipherView({
|
||||
edit: false,
|
||||
login: {
|
||||
uris: [{ uri: "https://example.com/login" }],
|
||||
},
|
||||
});
|
||||
const [doc, isInactive] = (component as any).isInactive2faCipher(cipher);
|
||||
expect(isInactive).toBe(false);
|
||||
expect(doc).toBe("");
|
||||
});
|
||||
|
||||
it("should return false if cipher does not have viewPassword", () => {
|
||||
const cipher = createCipherView({
|
||||
viewPassword: false,
|
||||
login: {
|
||||
uris: [{ uri: "https://example.com/login" }],
|
||||
},
|
||||
});
|
||||
const [doc, isInactive] = (component as any).isInactive2faCipher(cipher);
|
||||
expect(isInactive).toBe(false);
|
||||
expect(doc).toBe("");
|
||||
});
|
||||
|
||||
it("should check all uris and return true if any matches domain or host", () => {
|
||||
const cipher = createCipherView({
|
||||
login: {
|
||||
uris: [
|
||||
{ uri: "https://otherdomain.com/login" },
|
||||
{ uri: "https://sub.example.com/dashboard" },
|
||||
],
|
||||
},
|
||||
});
|
||||
const [doc, isInactive] = (component as any).isInactive2faCipher(cipher);
|
||||
expect(isInactive).toBe(true);
|
||||
expect(doc).toBe("https://sub.example.com/2fa-doc");
|
||||
});
|
||||
|
||||
it("should return false if uris array is empty", () => {
|
||||
const cipher = createCipherView({
|
||||
login: {
|
||||
uris: [],
|
||||
},
|
||||
});
|
||||
const [doc, isInactive] = (component as any).isInactive2faCipher(cipher);
|
||||
expect(isInactive).toBe(false);
|
||||
expect(doc).toBe("");
|
||||
});
|
||||
|
||||
function createCipherView({
|
||||
type = 1,
|
||||
login = {},
|
||||
isDeleted = false,
|
||||
edit = true,
|
||||
viewPassword = true,
|
||||
}: any): any {
|
||||
return {
|
||||
id: "test-id",
|
||||
type,
|
||||
login: {
|
||||
totp: null,
|
||||
hasUris: true,
|
||||
uris: [],
|
||||
...login,
|
||||
},
|
||||
isDeleted,
|
||||
edit,
|
||||
viewPassword,
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -109,7 +109,18 @@ export class InactiveTwoFactorReportComponent extends CipherReportComponent impl
|
||||
const u = login.uris[i];
|
||||
if (u.uri != null && u.uri !== "") {
|
||||
const uri = u.uri.replace("www.", "");
|
||||
const host = Utils.getHost(uri);
|
||||
const domain = Utils.getDomain(uri);
|
||||
// check host first
|
||||
if (host != null && this.services.has(host)) {
|
||||
if (this.services.get(host) != null) {
|
||||
docFor2fa = this.services.get(host) || "";
|
||||
}
|
||||
isInactive2faCipher = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// then check domain
|
||||
if (domain != null && this.services.has(domain)) {
|
||||
if (this.services.get(domain) != null) {
|
||||
docFor2fa = this.services.get(domain) || "";
|
||||
|
||||
Reference in New Issue
Block a user