From 2f8d2ac3cbf1993105cd53d9f502606748ff0625 Mon Sep 17 00:00:00 2001 From: Jonathan Prusik Date: Fri, 15 Nov 2024 17:09:46 -0500 Subject: [PATCH] add dismissable banner to the vault view when the active autofill tab is on the blocked domains list --- apps/browser/src/_locales/en/messages.json | 6 +++ .../components/vault/vault-v2.component.html | 9 ++++ .../components/vault/vault-v2.component.ts | 51 ++++++++++++++++++- .../src/models/domain/domain-service.ts | 2 +- 4 files changed, 65 insertions(+), 3 deletions(-) diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 4ec1a97abbc..85937b63304 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -2339,6 +2339,12 @@ "blockedDomainsDesc": { "message": "Autofill and other related features will not be offered for these websites. You must refresh the page for changes to take effect." }, + "autofillBlockedNotice": { + "message": "Autofill is blocked for this website. Review or change this in settings." + }, + "autofillBlockedTooltip": { + "message": "Autofill is blocked on this website. Review in settings." + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { diff --git a/apps/browser/src/vault/popup/components/vault/vault-v2.component.html b/apps/browser/src/vault/popup/components/vault/vault-v2.component.html index 4798ddf4dfb..651a976ff2b 100644 --- a/apps/browser/src/vault/popup/components/vault/vault-v2.component.html +++ b/apps/browser/src/vault/popup/components/vault/vault-v2.component.html @@ -22,6 +22,15 @@ + + {{ "autofillBlockedNotice" | i18n }} + + = this.vaultPopupListFiltersService.filters$.pipe( @@ -86,6 +92,8 @@ export class VaultV2Component implements OnInit, OnDestroy { constructor( private vaultPopupItemsService: VaultPopupItemsService, private vaultPopupListFiltersService: VaultPopupListFiltersService, + private domainSettingsService: DomainSettingsService, + private vaultPopupAutofillService: VaultPopupAutofillService, private vaultUiOnboardingService: VaultUiOnboardingService, ) { combineLatest([ @@ -110,6 +118,27 @@ export class VaultV2Component implements OnInit, OnDestroy { this.vaultState = null; } }); + + combineLatest([ + this.domainSettingsService.blockedInteractionsUris$, + this.vaultPopupAutofillService.currentAutofillTab$, + ]) + .pipe(takeUntilDestroyed()) + .subscribe(([blockedInteractionsUris, currentAutofillTab]) => { + if (blockedInteractionsUris && currentAutofillTab?.url?.length) { + const autofillTabURL = new URL(currentAutofillTab.url); + this.autofillTabHostname = autofillTabURL.hostname; + const autofillTabIsBlocked = Object.keys(blockedInteractionsUris).includes( + autofillTabURL.hostname, + ); + + this.scriptInjectionIsBlocked = autofillTabIsBlocked; + + this.showScriptInjectionIsBlockedBanner = + autofillTabIsBlocked && + !blockedInteractionsUris[autofillTabURL.hostname]?.bannerIsDismissed; + } + }); } async ngOnInit() { @@ -117,4 +146,22 @@ export class VaultV2Component implements OnInit, OnDestroy { } ngOnDestroy(): void {} + + handleScriptInjectionIsBlockedBannerDismiss() { + firstValueFrom(this.domainSettingsService.blockedInteractionsUris$) + .then((blockedURIs) => { + this.showScriptInjectionIsBlockedBanner = false; + this.domainSettingsService + .setBlockedInteractionsUris({ + ...blockedURIs, + [this.autofillTabHostname]: { bannerIsDismissed: true }, + }) + .catch(() => { + /* no-op */ + }); + }) + .catch(() => { + /* no-op */ + }); + } } diff --git a/libs/common/src/models/domain/domain-service.ts b/libs/common/src/models/domain/domain-service.ts index 9ff53cc8787..a6b5ecfdaac 100644 --- a/libs/common/src/models/domain/domain-service.ts +++ b/libs/common/src/models/domain/domain-service.ts @@ -21,5 +21,5 @@ export const UriMatchStrategy = { export type UriMatchStrategySetting = (typeof UriMatchStrategy)[keyof typeof UriMatchStrategy]; // using uniqueness properties of object shape over Set for ease of state storability -export type NeverDomains = { [id: string]: null }; +export type NeverDomains = { [id: string]: null | { bannerIsDismissed?: boolean } }; export type EquivalentDomains = string[][];