mirror of
https://github.com/bitwarden/browser
synced 2025-12-11 05:43:41 +00:00
[PM-14571] At Risk Passwords - Badge Update (#15983)
* add exclamation badge for at risk passwords on tab
* add berry icon for the badge when pending tasks are present
* remove integration wtih autofill for pending task badge
* add ability to override Never match strategy
- This is helpful for non-autofill purposes but cipher matching is still needed. This will default to the domain.
* add at-risk-cipher badge updater service
* Revert "add exclamation badge for at risk passwords on tab"
This reverts commit a9643c03d5.
* remove nullish-coalescing
* ensure that all user related observables use the same user.id
---------
Co-authored-by: Shane Melton <smelton@bitwarden.com>
This commit is contained in:
@@ -65,12 +65,16 @@ export abstract class CipherService implements UserKeyRotationDataProvider<Ciphe
|
||||
userId: UserId,
|
||||
includeOtherTypes?: CipherType[],
|
||||
defaultMatch?: UriMatchStrategySetting,
|
||||
/** When true, will override the match strategy for the cipher if it is Never. */
|
||||
overrideNeverMatchStrategy?: true,
|
||||
): Promise<CipherView[]>;
|
||||
abstract filterCiphersForUrl<C extends CipherViewLike = CipherView>(
|
||||
ciphers: C[],
|
||||
url: string,
|
||||
includeOtherTypes?: CipherType[],
|
||||
defaultMatch?: UriMatchStrategySetting,
|
||||
/** When true, will override the match strategy for the cipher if it is Never. */
|
||||
overrideNeverMatchStrategy?: true,
|
||||
): Promise<C[]>;
|
||||
abstract getAllFromApiForOrganization(organizationId: string): Promise<CipherView[]>;
|
||||
/**
|
||||
|
||||
@@ -111,6 +111,33 @@ describe("LoginUriView", () => {
|
||||
|
||||
expect(actual).toBe(false);
|
||||
});
|
||||
|
||||
it("overrides Never match strategy with Domain when parameter is set", () => {
|
||||
const loginUri = new LoginUriView();
|
||||
loginUri.uri = "https://example.org";
|
||||
loginUri.match = UriMatchStrategy.Never;
|
||||
|
||||
expect(loginUri.matchesUri("https://example.org", new Set(), undefined, true)).toBe(true);
|
||||
expect(loginUri.matchesUri("https://example.org", new Set(), undefined)).toBe(false);
|
||||
});
|
||||
|
||||
it("overrides Never match strategy when passed in as default strategy", () => {
|
||||
const loginUriNoMatch = new LoginUriView();
|
||||
loginUriNoMatch.uri = "https://example.org";
|
||||
|
||||
expect(
|
||||
loginUriNoMatch.matchesUri(
|
||||
"https://example.org",
|
||||
new Set(),
|
||||
UriMatchStrategy.Never,
|
||||
true,
|
||||
),
|
||||
).toBe(true);
|
||||
|
||||
expect(
|
||||
loginUriNoMatch.matchesUri("https://example.org", new Set(), UriMatchStrategy.Never),
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("using host matching", () => {
|
||||
|
||||
@@ -142,6 +142,8 @@ export class LoginUriView implements View {
|
||||
targetUri: string,
|
||||
equivalentDomains: Set<string>,
|
||||
defaultUriMatch: UriMatchStrategySetting = null,
|
||||
/** When present, will override the match strategy for the cipher if it is `Never` with `Domain` */
|
||||
overrideNeverMatchStrategy?: true,
|
||||
): boolean {
|
||||
if (!this.uri || !targetUri) {
|
||||
return false;
|
||||
@@ -150,6 +152,12 @@ export class LoginUriView implements View {
|
||||
let matchType = this.match ?? defaultUriMatch;
|
||||
matchType ??= UriMatchStrategy.Domain;
|
||||
|
||||
// Override the match strategy with `Domain` when it is `Never` and `overrideNeverMatchStrategy` is true.
|
||||
// This is useful in scenarios when the cipher should be matched to rely other information other than autofill.
|
||||
if (overrideNeverMatchStrategy && matchType === UriMatchStrategy.Never) {
|
||||
matchType = UriMatchStrategy.Domain;
|
||||
}
|
||||
|
||||
const targetDomain = Utils.getDomain(targetUri);
|
||||
const matchDomains = equivalentDomains.add(targetDomain);
|
||||
|
||||
|
||||
@@ -82,12 +82,16 @@ export class LoginView extends ItemView {
|
||||
targetUri: string,
|
||||
equivalentDomains: Set<string>,
|
||||
defaultUriMatch: UriMatchStrategySetting = null,
|
||||
/** When present, will override the match strategy for the cipher if it is `Never` with `Domain` */
|
||||
overrideNeverMatchStrategy?: true,
|
||||
): boolean {
|
||||
if (this.uris == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.uris.some((uri) => uri.matchesUri(targetUri, equivalentDomains, defaultUriMatch));
|
||||
return this.uris.some((uri) =>
|
||||
uri.matchesUri(targetUri, equivalentDomains, defaultUriMatch, overrideNeverMatchStrategy),
|
||||
);
|
||||
}
|
||||
|
||||
static fromJSON(obj: Partial<DeepJsonify<LoginView>>): LoginView {
|
||||
|
||||
@@ -601,6 +601,7 @@ export class CipherService implements CipherServiceAbstraction {
|
||||
userId: UserId,
|
||||
includeOtherTypes?: CipherType[],
|
||||
defaultMatch: UriMatchStrategySetting = null,
|
||||
overrideNeverMatchStrategy?: true,
|
||||
): Promise<CipherView[]> {
|
||||
return await firstValueFrom(
|
||||
this.cipherViews$(userId).pipe(
|
||||
@@ -612,6 +613,7 @@ export class CipherService implements CipherServiceAbstraction {
|
||||
url,
|
||||
includeOtherTypes,
|
||||
defaultMatch,
|
||||
overrideNeverMatchStrategy,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -623,6 +625,7 @@ export class CipherService implements CipherServiceAbstraction {
|
||||
url: string,
|
||||
includeOtherTypes?: CipherType[],
|
||||
defaultMatch: UriMatchStrategySetting = null,
|
||||
overrideNeverMatchStrategy?: true,
|
||||
): Promise<C[]> {
|
||||
if (url == null && includeOtherTypes == null) {
|
||||
return [];
|
||||
@@ -647,7 +650,13 @@ export class CipherService implements CipherServiceAbstraction {
|
||||
}
|
||||
|
||||
if (cipherIsLogin) {
|
||||
return CipherViewLikeUtils.matchesUri(cipher, url, equivalentDomains, defaultMatch);
|
||||
return CipherViewLikeUtils.matchesUri(
|
||||
cipher,
|
||||
url,
|
||||
equivalentDomains,
|
||||
defaultMatch,
|
||||
overrideNeverMatchStrategy,
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -174,13 +174,19 @@ export class CipherViewLikeUtils {
|
||||
targetUri: string,
|
||||
equivalentDomains: Set<string>,
|
||||
defaultUriMatch: UriMatchStrategySetting = UriMatchStrategy.Domain,
|
||||
overrideNeverMatchStrategy?: true,
|
||||
): boolean => {
|
||||
if (CipherViewLikeUtils.getType(cipher) !== CipherType.Login) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.isCipherListView(cipher)) {
|
||||
return cipher.login.matchesUri(targetUri, equivalentDomains, defaultUriMatch);
|
||||
return cipher.login.matchesUri(
|
||||
targetUri,
|
||||
equivalentDomains,
|
||||
defaultUriMatch,
|
||||
overrideNeverMatchStrategy,
|
||||
);
|
||||
}
|
||||
|
||||
const login = this.getLogin(cipher);
|
||||
@@ -198,7 +204,7 @@ export class CipherViewLikeUtils {
|
||||
});
|
||||
|
||||
return loginUriViews.some((uriView) =>
|
||||
uriView.matchesUri(targetUri, equivalentDomains, defaultUriMatch),
|
||||
uriView.matchesUri(targetUri, equivalentDomains, defaultUriMatch, overrideNeverMatchStrategy),
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user