mirror of
https://github.com/bitwarden/browser
synced 2025-12-19 09:43:23 +00:00
add dismissable banner to the vault view when the active autofill tab is on the blocked domains list
This commit is contained in:
@@ -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": {
|
||||
|
||||
@@ -22,6 +22,15 @@
|
||||
</bit-no-items>
|
||||
</div>
|
||||
|
||||
<bit-banner
|
||||
*ngIf="vaultState !== VaultStateEnum.Empty && showScriptInjectionIsBlockedBanner"
|
||||
id="domain-script-injection-blocked-banner"
|
||||
bannerType="info"
|
||||
(onClose)="handleScriptInjectionIsBlockedBannerDismiss()"
|
||||
>
|
||||
{{ "autofillBlockedNotice" | i18n }}
|
||||
</bit-banner>
|
||||
|
||||
<!-- Show search & filters outside of the scroll area of the page -->
|
||||
<ng-container
|
||||
slot="above-scroll-area"
|
||||
|
||||
@@ -3,18 +3,20 @@ import { CommonModule } from "@angular/common";
|
||||
import { Component, OnDestroy, OnInit } from "@angular/core";
|
||||
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
||||
import { RouterLink } from "@angular/router";
|
||||
import { combineLatest, Observable, shareReplay, switchMap } from "rxjs";
|
||||
import { combineLatest, firstValueFrom, Observable, shareReplay, switchMap } from "rxjs";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { DomainSettingsService } from "@bitwarden/common/autofill/services/domain-settings.service";
|
||||
import { CollectionId, OrganizationId } from "@bitwarden/common/types/guid";
|
||||
import { CipherType } from "@bitwarden/common/vault/enums";
|
||||
import { ButtonModule, Icons, NoItemsModule } from "@bitwarden/components";
|
||||
import { BannerModule, ButtonModule, Icons, NoItemsModule } from "@bitwarden/components";
|
||||
import { VaultIcons } from "@bitwarden/vault";
|
||||
|
||||
import { CurrentAccountComponent } from "../../../../auth/popup/account-switching/current-account.component";
|
||||
import { PopOutComponent } from "../../../../platform/popup/components/pop-out.component";
|
||||
import { PopupHeaderComponent } from "../../../../platform/popup/layout/popup-header.component";
|
||||
import { PopupPageComponent } from "../../../../platform/popup/layout/popup-page.component";
|
||||
import { VaultPopupAutofillService } from "../../services/vault-popup-autofill.service";
|
||||
import { VaultPopupItemsService } from "../../services/vault-popup-items.service";
|
||||
import { VaultPopupListFiltersService } from "../../services/vault-popup-list-filters.service";
|
||||
import { VaultUiOnboardingService } from "../../services/vault-ui-onboarding.service";
|
||||
@@ -45,6 +47,7 @@ enum VaultState {
|
||||
CommonModule,
|
||||
AutofillVaultListItemsComponent,
|
||||
VaultListItemsContainerComponent,
|
||||
BannerModule,
|
||||
ButtonModule,
|
||||
RouterLink,
|
||||
NewItemDropdownV2Component,
|
||||
@@ -59,6 +62,9 @@ export class VaultV2Component implements OnInit, OnDestroy {
|
||||
protected favoriteCiphers$ = this.vaultPopupItemsService.favoriteCiphers$;
|
||||
protected remainingCiphers$ = this.vaultPopupItemsService.remainingCiphers$;
|
||||
protected loading$ = this.vaultPopupItemsService.loading$;
|
||||
protected scriptInjectionIsBlocked = false;
|
||||
protected showScriptInjectionIsBlockedBanner = false;
|
||||
protected autofillTabHostname: string = null;
|
||||
|
||||
protected newItemItemValues$: Observable<NewItemInitialValues> =
|
||||
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 */
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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[][];
|
||||
|
||||
Reference in New Issue
Block a user