diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index 3382948046..4119268808 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -980,8 +980,8 @@ "commandLockVaultDesc": { "message": "Lock the vault" }, - "privateModeMessage": { - "message": "Unfortunately this window is not available in private mode for this browser." + "privateModeWarning": { + "message": "Private mode support is experimental and some features are limited." }, "customFields": { "message": "Custom Fields" diff --git a/src/background/main.background.ts b/src/background/main.background.ts index 70a12adbbf..5422178081 100644 --- a/src/background/main.background.ts +++ b/src/background/main.background.ts @@ -92,6 +92,7 @@ import { PopupUtilsService } from "../popup/services/popup-utils.service"; import AutofillService from "../services/autofill.service"; import { BrowserCryptoService } from "../services/browserCrypto.service"; import BrowserMessagingService from "../services/browserMessaging.service"; +import BrowserMessagingPrivateModeBackgroundService from "../services/browserMessagingPrivateModeBackground.service"; import BrowserPlatformUtilsService from "../services/browserPlatformUtils.service"; import BrowserStorageService from "../services/browserStorage.service"; import I18nService from "../services/i18n.service"; @@ -100,7 +101,6 @@ import VaultTimeoutService from "../services/vaultTimeout.service"; import { Account } from "../models/account"; -import { GlobalStateFactory } from "jslib-common/factories/globalStateFactory"; import { StateFactory } from "jslib-common/factories/stateFactory"; export default class MainBackground { @@ -165,9 +165,11 @@ export default class MainBackground { private isSafari: boolean; private nativeMessagingBackground: NativeMessagingBackground; - constructor() { + constructor(public isPrivateMode: boolean = false) { // Services - this.messagingService = new BrowserMessagingService(); + this.messagingService = isPrivateMode + ? new BrowserMessagingPrivateModeBackgroundService() + : new BrowserMessagingService(); this.storageService = new BrowserStorageService(); this.secureStorageService = new BrowserStorageService(); this.logService = new ConsoleLogService(false); @@ -362,7 +364,7 @@ export default class MainBackground { this.logService, this.stateService ); - this.popupUtilsService = new PopupUtilsService(this.platformUtilsService); + this.popupUtilsService = new PopupUtilsService(isPrivateMode); this.userVerificationService = new UserVerificationService( this.cryptoService, @@ -404,7 +406,6 @@ export default class MainBackground { this.systemService, this.environmentService, this.messagingService, - this.stateService, this.logService ); this.nativeMessagingBackground = new NativeMessagingBackground( @@ -502,6 +503,16 @@ export default class MainBackground { await this.webRequestBackground.init(); await this.windowsBackground.init(); + if (this.platformUtilsService.isFirefox && !this.isPrivateMode) { + // Set new Private Mode windows to the default icon - they do not share state with the background page + BrowserApi.onWindowCreated(async (win) => { + if (win.incognito) { + await this.actionSetIcon(chrome.browserAction, "", win.id); + await this.actionSetIcon(this.sidebarAction, "", win.id); + } + }); + } + return new Promise((resolve) => { setTimeout(async () => { await this.environmentService.setUrlsFromStorage(); @@ -514,7 +525,7 @@ export default class MainBackground { } async setIcon() { - if (!chrome.browserAction && !this.sidebarAction) { + if ((!chrome.browserAction && !this.sidebarAction) || this.isPrivateMode) { return; } @@ -928,7 +939,7 @@ export default class MainBackground { }); } - private async actionSetIcon(theAction: any, suffix: string): Promise { + private async actionSetIcon(theAction: any, suffix: string, windowId?: number): Promise { if (!theAction || !theAction.setIcon) { return; } @@ -938,6 +949,7 @@ export default class MainBackground { 19: "images/icon19" + suffix + ".png", 38: "images/icon38" + suffix + ".png", }, + windowId: windowId, }; if (this.platformUtilsService.isFirefox()) { diff --git a/src/background/runtime.background.ts b/src/background/runtime.background.ts index 5d1a31e142..78cf6d16ba 100644 --- a/src/background/runtime.background.ts +++ b/src/background/runtime.background.ts @@ -31,7 +31,6 @@ export default class RuntimeBackground { private systemService: SystemService, private environmentService: EnvironmentService, private messagingService: MessagingService, - private stateService: StateService, private logService: LogService ) { // onInstalled listener must be wired up before anything else, so we do it in the ctor @@ -46,12 +45,18 @@ export default class RuntimeBackground { } await this.checkOnInstalled(); - BrowserApi.messageListener( - "runtime.background", - async (msg: any, sender: chrome.runtime.MessageSender, sendResponse: any) => { - await this.processMessage(msg, sender, sendResponse); - } - ); + const backgroundMessageListener = async ( + msg: any, + sender: chrome.runtime.MessageSender, + sendResponse: any + ) => { + await this.processMessage(msg, sender, sendResponse); + }; + + BrowserApi.messageListener("runtime.background", backgroundMessageListener); + if (this.main.isPrivateMode) { + (window as any).bitwardenBackgroundMessageListener = backgroundMessageListener; + } } async processMessage(msg: any, sender: any, sendResponse: any) { @@ -60,7 +65,7 @@ export default class RuntimeBackground { case "unlocked": let item: LockedVaultPendingNotificationsItem; - if (this.lockedVaultPendingNotifications.length > 0) { + if (this.lockedVaultPendingNotifications?.length > 0) { await BrowserApi.closeLoginTab(); item = this.lockedVaultPendingNotifications.pop(); diff --git a/src/browser/browserApi.ts b/src/browser/browserApi.ts index 0c3b7a79f1..3f19a83975 100644 --- a/src/browser/browserApi.ts +++ b/src/browser/browserApi.ts @@ -84,6 +84,14 @@ export class BrowserApi { }); } + static async getPrivateModeWindows(): Promise { + return (await browser.windows.getAll()).filter((win) => win.incognito); + } + + static async onWindowCreated(callback: (win: chrome.windows.Window) => any) { + return chrome.windows.onCreated.addListener(callback); + } + static getBackgroundPage(): any { return chrome.extension.getBackgroundPage(); } diff --git a/src/popup/accounts/lock.component.html b/src/popup/accounts/lock.component.html index 0d41f2d712..68edd697a4 100644 --- a/src/popup/accounts/lock.component.html +++ b/src/popup/accounts/lock.component.html @@ -70,5 +70,6 @@

+ diff --git a/src/popup/accounts/login.component.html b/src/popup/accounts/login.component.html index 1ae52bc201..df5c1e836a 100644 --- a/src/popup/accounts/login.component.html +++ b/src/popup/accounts/login.component.html @@ -67,5 +67,6 @@

{{ "getMasterPasswordHint" | i18n }}

+ diff --git a/src/popup/app-routing.module.ts b/src/popup/app-routing.module.ts index 9c7acd60ed..4860cc2a2b 100644 --- a/src/popup/app-routing.module.ts +++ b/src/popup/app-routing.module.ts @@ -3,9 +3,9 @@ import { ActivatedRouteSnapshot, RouteReuseStrategy, RouterModule, Routes } from import { AuthGuardService } from "jslib-angular/services/auth-guard.service"; import { LockGuardService } from "jslib-angular/services/lock-guard.service"; +import { UnauthGuardService } from "jslib-angular/services/unauth-guard.service"; import { DebounceNavigationService } from "./services/debounceNavigationService"; -import { LaunchGuardService } from "./services/launch-guard.service"; import { EnvironmentComponent } from "./accounts/environment.component"; import { HintComponent } from "./accounts/hint.component"; @@ -23,7 +23,6 @@ import { UpdateTempPasswordComponent } from "./accounts/update-temp-password.com import { PasswordGeneratorHistoryComponent } from "./generator/password-generator-history.component"; import { PasswordGeneratorComponent } from "./generator/password-generator.component"; -import { PrivateModeComponent } from "./private-mode.component"; import { TabsComponent } from "./tabs.component"; import { ExcludedDomainsComponent } from "./settings/excluded-domains.component"; @@ -63,13 +62,13 @@ const routes: Routes = [ { path: "home", component: HomeComponent, - canActivate: [LaunchGuardService], + canActivate: [UnauthGuardService], data: { state: "home" }, }, { path: "login", component: LoginComponent, - canActivate: [LaunchGuardService], + canActivate: [UnauthGuardService], data: { state: "login" }, }, { @@ -81,19 +80,19 @@ const routes: Routes = [ { path: "2fa", component: TwoFactorComponent, - canActivate: [LaunchGuardService], + canActivate: [UnauthGuardService], data: { state: "2fa" }, }, { path: "2fa-options", component: TwoFactorOptionsComponent, - canActivate: [LaunchGuardService], + canActivate: [UnauthGuardService], data: { state: "2fa-options" }, }, { path: "sso", component: SsoComponent, - canActivate: [LaunchGuardService], + canActivate: [UnauthGuardService], data: { state: "sso" }, }, { @@ -110,19 +109,19 @@ const routes: Routes = [ { path: "register", component: RegisterComponent, - canActivate: [LaunchGuardService], + canActivate: [UnauthGuardService], data: { state: "register" }, }, { path: "hint", component: HintComponent, - canActivate: [LaunchGuardService], + canActivate: [UnauthGuardService], data: { state: "hint" }, }, { path: "environment", component: EnvironmentComponent, - canActivate: [LaunchGuardService], + canActivate: [UnauthGuardService], data: { state: "environment" }, }, { @@ -235,11 +234,6 @@ const routes: Routes = [ canActivate: [AuthGuardService], data: { state: "options" }, }, - { - path: "private-mode", - component: PrivateModeComponent, - data: { state: "private-mode" }, - }, { path: "clone-cipher", component: AddEditComponent, diff --git a/src/popup/app.component.ts b/src/popup/app.component.ts index d018b2ca4d..8f447f641e 100644 --- a/src/popup/app.component.ts +++ b/src/popup/app.component.ts @@ -8,7 +8,6 @@ import { BrowserApi } from "../browser/browserApi"; import { AuthService } from "jslib-common/abstractions/auth.service"; import { BroadcasterService } from "jslib-common/abstractions/broadcaster.service"; import { I18nService } from "jslib-common/abstractions/i18n.service"; -import { KeyConnectorService } from "jslib-common/abstractions/keyConnector.service"; import { MessagingService } from "jslib-common/abstractions/messaging.service"; import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service"; @@ -39,14 +38,10 @@ export class AppComponent implements OnInit { private changeDetectorRef: ChangeDetectorRef, private ngZone: NgZone, private sanitizer: DomSanitizer, - private platformUtilsService: PlatformUtilsService, - private keyConnectoService: KeyConnectorService + private platformUtilsService: PlatformUtilsService ) {} ngOnInit() { - if (BrowserApi.getBackgroundPage() == null) { - return; - } this.stateService.activeAccount.subscribe((userId) => { this.activeUserId = userId; }); diff --git a/src/popup/app.module.ts b/src/popup/app.module.ts index 9d86c7a029..e148e92ab9 100644 --- a/src/popup/app.module.ts +++ b/src/popup/app.module.ts @@ -27,7 +27,6 @@ import { PasswordGeneratorHistoryComponent } from "./generator/password-generato import { PasswordGeneratorComponent } from "./generator/password-generator.component"; import { AppComponent } from "./app.component"; -import { PrivateModeComponent } from "./private-mode.component"; import { TabsComponent } from "./tabs.component"; import { ExcludedDomainsComponent } from "./settings/excluded-domains.component"; @@ -78,6 +77,7 @@ import { ActionButtonsComponent } from "./components/action-buttons.component"; import { CipherRowComponent } from "./components/cipher-row.component"; import { PasswordRepromptComponent } from "./components/password-reprompt.component"; import { PopOutComponent } from "./components/pop-out.component"; +import { PrivateModeWarningComponent } from "./components/private-mode-warning.component"; import { SendListComponent } from "./components/send-list.component"; import { SetPinComponent } from "./components/set-pin.component"; import { VerifyMasterPasswordComponent } from "./components/verify-master-password.component"; @@ -230,7 +230,7 @@ registerLocaleData(localeZhTw, "zh-TW"); PasswordRepromptComponent, PopOutComponent, PremiumComponent, - PrivateModeComponent, + PrivateModeWarningComponent, RegisterComponent, SearchCiphersPipe, SelectCopyDirective, diff --git a/src/popup/components/private-mode-warning.component.html b/src/popup/components/private-mode-warning.component.html new file mode 100644 index 0000000000..848b69c92d --- /dev/null +++ b/src/popup/components/private-mode-warning.component.html @@ -0,0 +1,6 @@ + + {{ "privateModeWarning" | i18n }} + {{ + "learnMore" | i18n + }} + diff --git a/src/popup/components/private-mode-warning.component.ts b/src/popup/components/private-mode-warning.component.ts new file mode 100644 index 0000000000..da011536e4 --- /dev/null +++ b/src/popup/components/private-mode-warning.component.ts @@ -0,0 +1,16 @@ +import { Component, OnInit } from "@angular/core"; +import { PopupUtilsService } from "../services/popup-utils.service"; + +@Component({ + selector: "app-private-mode-warning", + templateUrl: "private-mode-warning.component.html", +}) +export class PrivateModeWarningComponent implements OnInit { + showWarning = false; + + constructor(private popupUtilsService: PopupUtilsService) {} + + ngOnInit() { + this.showWarning = this.popupUtilsService.inPrivateMode(); + } +} diff --git a/src/popup/private-mode.component.html b/src/popup/private-mode.component.html deleted file mode 100644 index a1758be4f4..0000000000 --- a/src/popup/private-mode.component.html +++ /dev/null @@ -1,6 +0,0 @@ -
-

{{ privateModeMessage }}

- -
diff --git a/src/popup/private-mode.component.ts b/src/popup/private-mode.component.ts deleted file mode 100644 index c1507557d5..0000000000 --- a/src/popup/private-mode.component.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { BrowserApi } from "../browser/browserApi"; - -import { Component, OnInit } from "@angular/core"; - -@Component({ - selector: "app-private-mode", - templateUrl: "private-mode.component.html", -}) -export class PrivateModeComponent implements OnInit { - privateModeMessage: string; - learnMoreMessage: string; - - ngOnInit() { - this.privateModeMessage = chrome.i18n.getMessage("privateModeMessage"); - this.learnMoreMessage = chrome.i18n.getMessage("learnMore"); - } - - learnMore() { - BrowserApi.createNewTab("https://bitwarden.com/help/extension-wont-load-in-private-mode/"); - } -} diff --git a/src/popup/scss/pages.scss b/src/popup/scss/pages.scss index 4134f9b560..061b7a8b23 100644 --- a/src/popup/scss/pages.scss +++ b/src/popup/scss/pages.scss @@ -73,6 +73,11 @@ app-home { } } +app-private-mode-warning { + display: block; + padding-top: 1rem; +} + body.body-sm, body.body-xs { app-home { diff --git a/src/popup/services/launch-guard.service.ts b/src/popup/services/launch-guard.service.ts deleted file mode 100644 index 9ef631efbe..0000000000 --- a/src/popup/services/launch-guard.service.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { BrowserApi } from "../../browser/browserApi"; - -import { Injectable } from "@angular/core"; -import { CanActivate, Router } from "@angular/router"; - -import { UnauthGuardService } from "jslib-angular/services/unauth-guard.service"; - -@Injectable() -export class LaunchGuardService implements CanActivate { - constructor(private router: Router, private unauthGuardService: UnauthGuardService) {} - - async canActivate() { - if (BrowserApi.getBackgroundPage() == null) { - this.router.navigate(["private-mode"]); - return false; - } - return await this.unauthGuardService.canActivate(); - } -} diff --git a/src/popup/services/popup-utils.service.ts b/src/popup/services/popup-utils.service.ts index 64c880ce9a..a9de6e6d66 100644 --- a/src/popup/services/popup-utils.service.ts +++ b/src/popup/services/popup-utils.service.ts @@ -2,11 +2,9 @@ import { Injectable } from "@angular/core"; import { BrowserApi } from "../../browser/browserApi"; -import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service"; - @Injectable() export class PopupUtilsService { - constructor(private platformUtilsService: PlatformUtilsService) {} + constructor(private privateMode: boolean = false) {} inSidebar(win: Window): boolean { return win.location.search !== "" && win.location.search.indexOf("uilocation=sidebar") > -1; @@ -28,6 +26,10 @@ export class PopupUtilsService { ); } + inPrivateMode(): boolean { + return this.privateMode; + } + getContentScrollY(win: Window, scrollingContainer: string = "content"): number { const content = win.document.getElementsByTagName(scrollingContainer)[0]; return content.scrollTop; diff --git a/src/popup/services/services.module.ts b/src/popup/services/services.module.ts index 511a547f70..81dc7d53a9 100644 --- a/src/popup/services/services.module.ts +++ b/src/popup/services/services.module.ts @@ -1,7 +1,6 @@ import { APP_INITIALIZER, LOCALE_ID, NgModule } from "@angular/core"; import { DebounceNavigationService } from "./debounceNavigationService"; -import { LaunchGuardService } from "./launch-guard.service"; import { LockGuardService } from "./lock-guard.service"; import { PasswordRepromptService } from "./password-reprompt.service"; import { UnauthGuardService } from "./unauth-guard.service"; @@ -49,7 +48,9 @@ import { UserVerificationService } from "jslib-common/abstractions/userVerificat import { VaultTimeoutService } from "jslib-common/abstractions/vaultTimeout.service"; import { AutofillService } from "../../services/abstractions/autofill.service"; + import BrowserMessagingService from "../../services/browserMessaging.service"; +import BrowserMessagingPrivateModePopupService from "../../services/browserMessagingPrivateModePopup.service"; import { AuthService } from "jslib-common/services/auth.service"; import { ConsoleLogService } from "jslib-common/services/consoleLog.service"; @@ -62,14 +63,24 @@ import { ThemeType } from "jslib-common/enums/themeType"; import { StateService as StateServiceAbstraction } from "../../services/abstractions/state.service"; -function getBgService(service: string) { - return (): T => { - const page = BrowserApi.getBackgroundPage(); - return page ? (page.bitwardenMain[service] as T) : null; - }; -} +import MainBackground from "../../background/main.background"; const isPrivateMode = BrowserApi.getBackgroundPage() == null; +const mainBackground: MainBackground = isPrivateMode + ? createLocalBgService() + : BrowserApi.getBackgroundPage().bitwardenMain; + +function createLocalBgService() { + const localBgService = new MainBackground(true); + localBgService.bootstrap(); + return localBgService; +} + +function getBgService(service: keyof MainBackground) { + return (): T => { + return mainBackground ? (mainBackground[service] as any as T) : null; + }; +} export function initFactory( platformUtilsService: PlatformUtilsService, @@ -89,33 +100,47 @@ export function initFactory( window.document.body.classList.add("body-sm"); } - if (!isPrivateMode) { - const htmlEl = window.document.documentElement; - const theme = await platformUtilsService.getEffectiveTheme(); - htmlEl.classList.add("theme_" + theme); - platformUtilsService.onDefaultSystemThemeChange(async (sysTheme) => { - const bwTheme = await stateService.getTheme(); - if (bwTheme == null || bwTheme === ThemeType.System) { - htmlEl.classList.remove("theme_" + ThemeType.Light, "theme_" + ThemeType.Dark); - htmlEl.classList.add("theme_" + sysTheme); - } - }); - htmlEl.classList.add("locale_" + i18nService.translationLocale); - - // Workaround for slow performance on external monitors on Chrome + MacOS - // See: https://bugs.chromium.org/p/chromium/issues/detail?id=971701#c64 - if ( - platformUtilsService.isChrome() && - navigator.platform.indexOf("Mac") > -1 && - popupUtilsService.inPopup(window) && - (window.screenLeft < 0 || - window.screenTop < 0 || - window.screenLeft > window.screen.width || - window.screenTop > window.screen.height) - ) { - htmlEl.classList.add("force_redraw"); - logService.info("Force redraw is on"); + const htmlEl = window.document.documentElement; + const theme = await platformUtilsService.getEffectiveTheme(); + htmlEl.classList.add("theme_" + theme); + platformUtilsService.onDefaultSystemThemeChange(async (sysTheme) => { + const bwTheme = await stateService.getTheme(); + if (bwTheme == null || bwTheme === ThemeType.System) { + htmlEl.classList.remove("theme_" + ThemeType.Light, "theme_" + ThemeType.Dark); + htmlEl.classList.add("theme_" + sysTheme); } + }); + htmlEl.classList.add("locale_" + i18nService.translationLocale); + + // Workaround for slow performance on external monitors on Chrome + MacOS + // See: https://bugs.chromium.org/p/chromium/issues/detail?id=971701#c64 + if ( + platformUtilsService.isChrome() && + navigator.platform.indexOf("Mac") > -1 && + popupUtilsService.inPopup(window) && + (window.screenLeft < 0 || + window.screenTop < 0 || + window.screenLeft > window.screen.width || + window.screenTop > window.screen.height) + ) { + htmlEl.classList.add("force_redraw"); + logService.info("Force redraw is on"); + } + htmlEl.classList.add("locale_" + i18nService.translationLocale); + + // Workaround for slow performance on external monitors on Chrome + MacOS + // See: https://bugs.chromium.org/p/chromium/issues/detail?id=971701#c64 + if ( + platformUtilsService.isChrome() && + navigator.platform.indexOf("Mac") > -1 && + popupUtilsService.inPopup(window) && + (window.screenLeft < 0 || + window.screenTop < 0 || + window.screenLeft > window.screen.width || + window.screenTop > window.screen.height) + ) { + htmlEl.classList.add("force_redraw"); + logService.info("Force redraw is on"); } }; } @@ -126,8 +151,7 @@ export function initFactory( providers: [ { provide: LOCALE_ID, - useFactory: () => - isPrivateMode ? null : getBgService("i18nService")().translationLocale, + useFactory: () => getBgService("i18nService")().translationLocale, deps: [], }, { @@ -142,12 +166,23 @@ export function initFactory( ], multi: true, }, - LaunchGuardService, { provide: BaseLockGuardService, useClass: LockGuardService }, { provide: BaseUnauthGuardService, useClass: UnauthGuardService }, DebounceNavigationService, - PopupUtilsService, - { provide: MessagingService, useClass: BrowserMessagingService }, + { provide: PopupUtilsService, useFactory: () => new PopupUtilsService(isPrivateMode) }, + { + provide: MessagingService, + useFactory: () => { + return isPrivateMode + ? new BrowserMessagingPrivateModePopupService() + : new BrowserMessagingService(); + }, + }, + { + provide: TwoFactorService, + useFactory: getBgService("twoFactorService"), + deps: [], + }, { provide: TwoFactorService, useFactory: getBgService("twoFactorService"), @@ -165,14 +200,12 @@ export function initFactory( logService: ConsoleLogService, i18nService: I18nService ) => { - return isPrivateMode - ? null - : new PopupSearchService( - getBgService("searchService")(), - cipherService, - logService, - i18nService - ); + return new PopupSearchService( + getBgService("searchService")(), + cipherService, + logService, + i18nService + ); }, deps: [CipherService, LogServiceAbstraction, I18nService], }, diff --git a/src/services/browserMessagingPrivateModeBackground.service.ts b/src/services/browserMessagingPrivateModeBackground.service.ts new file mode 100644 index 0000000000..4ffdf763da --- /dev/null +++ b/src/services/browserMessagingPrivateModeBackground.service.ts @@ -0,0 +1,8 @@ +import { MessagingService } from "jslib-common/abstractions/messaging.service"; + +export default class BrowserMessagingPrivateModeBackgroundService implements MessagingService { + send(subscriber: string, arg: any = {}) { + const message = Object.assign({}, { command: subscriber }, arg); + (window as any).bitwardenPopupMainMessageListener(message); + } +} diff --git a/src/services/browserMessagingPrivateModePopup.service.ts b/src/services/browserMessagingPrivateModePopup.service.ts new file mode 100644 index 0000000000..0f3af10d86 --- /dev/null +++ b/src/services/browserMessagingPrivateModePopup.service.ts @@ -0,0 +1,8 @@ +import { MessagingService } from "jslib-common/abstractions/messaging.service"; + +export default class BrowserMessagingPrivateModePopupService implements MessagingService { + send(subscriber: string, arg: any = {}) { + const message = Object.assign({}, { command: subscriber }, arg); + (window as any).bitwardenBackgroundMessageListener(message); + } +} diff --git a/src/services/state.service.ts b/src/services/state.service.ts index ec6e9f1959..58ec0666a8 100644 --- a/src/services/state.service.ts +++ b/src/services/state.service.ts @@ -18,6 +18,15 @@ export class StateService await super.addAccount(account); } + async getIsAuthenticated(options?: StorageOptions): Promise { + // Firefox Private Mode can clash with non-Private Mode because they both read from the same onDiskOptions + // Check that there is an account in memory before considering the user authenticated + return ( + (await super.getIsAuthenticated(options)) && + (await this.getAccount(this.defaultInMemoryOptions)) != null + ); + } + async getBrowserGroupingComponentState( options?: StorageOptions ): Promise {