From dd4343c9805cca77763e1ae0f17c7f67743c77b3 Mon Sep 17 00:00:00 2001 From: gbubemismith Date: Mon, 7 Aug 2023 16:18:20 -0400 Subject: [PATCH] Refactored message listener observable to handle angular change detection --- apps/browser/src/platform/browser/browser-api.ts | 11 +++++++++-- .../popup/components/fido2/fido2.component.ts | 15 +++++---------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/apps/browser/src/platform/browser/browser-api.ts b/apps/browser/src/platform/browser/browser-api.ts index cb9778832e6..6d5485a934e 100644 --- a/apps/browser/src/platform/browser/browser-api.ts +++ b/apps/browser/src/platform/browser/browser-api.ts @@ -1,3 +1,4 @@ +import { NgZone } from "@angular/core"; import { Observable } from "rxjs"; import { DeviceType } from "@bitwarden/common/enums"; @@ -212,9 +213,15 @@ export class BrowserApi { } } - static messageListener$() { + static messageListener$(zone?: NgZone) { return new Observable((subscriber) => { - const handler = (message: unknown) => subscriber.next(message); + const handler = (message: unknown) => { + if (zone) { + zone.run(() => subscriber.next(message)); + } else { + subscriber.next(message); + } + }; chrome.runtime.onMessage.addListener(handler); return () => chrome.runtime.onMessage.removeListener(handler); }); diff --git a/apps/browser/src/vault/popup/components/fido2/fido2.component.ts b/apps/browser/src/vault/popup/components/fido2/fido2.component.ts index 562865dc8e3..d5f3030417e 100644 --- a/apps/browser/src/vault/popup/components/fido2/fido2.component.ts +++ b/apps/browser/src/vault/popup/components/fido2/fido2.component.ts @@ -18,6 +18,7 @@ import { CipherType } from "@bitwarden/common/vault/enums/cipher-type"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { Fido2KeyView } from "@bitwarden/common/vault/models/view/fido2-key.view"; +import { BrowserApi } from "../../../../platform/browser/browser-api"; import { BrowserFido2Message, BrowserFido2UserInterfaceSession, @@ -57,16 +58,10 @@ export class Fido2Component implements OnInit, OnDestroy { map((queryParamMap) => queryParamMap.get("sessionId")) ); - // Duplicated from BrowserApi.MessageListener$, but adds ngZone.run to make sure - // Angular change detection knows when a new value is emitted. Otherwise it is outside the zone. - // TODO: refactor so that this is reusable in other components to help others avoid this trap! - const messageListener$ = new Observable((subscriber) => { - const handler = (message: unknown) => this.ngZone.run(() => subscriber.next(message)); // <-- the magic is here - chrome.runtime.onMessage.addListener(handler); - return () => chrome.runtime.onMessage.removeListener(handler); - }) as Observable; - - combineLatest([sessionId$, messageListener$]) + combineLatest([ + sessionId$, + BrowserApi.messageListener$(this.ngZone) as Observable, + ]) .pipe(takeUntil(this.destroy$)) .subscribe(([sessionId, message]) => { this.sessionId = sessionId;