From f79d1592773574f7495337c885c437ceeccc31d4 Mon Sep 17 00:00:00 2001 From: rr-bw <102181210+rr-bw@users.noreply.github.com> Date: Tue, 2 Apr 2024 10:16:42 -0700 Subject: [PATCH] [PM-5500] Implement StateProvider in RouterService (#8119) * implement StateProvider in RouterService * Remove 'export' Co-authored-by: Andreas Coroiu * Skip parameter Co-authored-by: Andreas Coroiu --------- Co-authored-by: Andreas Coroiu --- apps/web/src/app/core/router.service.ts | 29 +++++++++++++++---- .../platform/abstractions/state.service.ts | 13 --------- .../platform/models/domain/global-state.ts | 1 - .../src/platform/services/state.service.ts | 17 ----------- .../src/platform/state/state-definitions.ts | 1 + 5 files changed, 25 insertions(+), 36 deletions(-) diff --git a/apps/web/src/app/core/router.service.ts b/apps/web/src/app/core/router.service.ts index 5a0d903ba7..caebb22733 100644 --- a/apps/web/src/app/core/router.service.ts +++ b/apps/web/src/app/core/router.service.ts @@ -1,14 +1,31 @@ import { Injectable } from "@angular/core"; import { Title } from "@angular/platform-browser"; import { ActivatedRoute, NavigationEnd, Router } from "@angular/router"; -import { filter } from "rxjs"; +import { filter, firstValueFrom } from "rxjs"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; +import { + KeyDefinition, + ROUTER_DISK, + StateProvider, + GlobalState, +} from "@bitwarden/common/platform/state"; + +const DEEP_LINK_REDIRECT_URL = new KeyDefinition(ROUTER_DISK, "deepLinkRedirectUrl", { + deserializer: (value: string) => value, +}); @Injectable() export class RouterService { + /** + * The string value of the URL the user tried to navigate to while unauthenticated. + * + * Developed to allow users to deep link even when the navigation gets interrupted + * by the authentication process. + */ + private deepLinkRedirectUrlState: GlobalState; + private previousUrl: string = undefined; private currentUrl: string = undefined; @@ -16,9 +33,11 @@ export class RouterService { private router: Router, private activatedRoute: ActivatedRoute, private titleService: Title, - private stateService: StateService, + private stateProvider: StateProvider, i18nService: I18nService, ) { + this.deepLinkRedirectUrlState = this.stateProvider.getGlobal(DEEP_LINK_REDIRECT_URL); + this.currentUrl = this.router.url; router.events @@ -67,14 +86,14 @@ export class RouterService { * @param url URL being saved to the Global State */ async persistLoginRedirectUrl(url: string): Promise { - await this.stateService.setDeepLinkRedirectUrl(url); + await this.deepLinkRedirectUrlState.update(() => url); } /** * Fetch and clear persisted LoginRedirectUrl if present in state */ async getAndClearLoginRedirectUrl(): Promise | undefined { - const persistedPreLoginUrl = await this.stateService.getDeepLinkRedirectUrl(); + const persistedPreLoginUrl = await firstValueFrom(this.deepLinkRedirectUrlState.state$); if (!Utils.isNullOrEmpty(persistedPreLoginUrl)) { await this.persistLoginRedirectUrl(null); diff --git a/libs/common/src/platform/abstractions/state.service.ts b/libs/common/src/platform/abstractions/state.service.ts index 4c876316cd..4971481381 100644 --- a/libs/common/src/platform/abstractions/state.service.ts +++ b/libs/common/src/platform/abstractions/state.service.ts @@ -243,18 +243,5 @@ export abstract class StateService { setVaultTimeoutAction: (value: string, options?: StorageOptions) => Promise; getApproveLoginRequests: (options?: StorageOptions) => Promise; setApproveLoginRequests: (value: boolean, options?: StorageOptions) => Promise; - /** - * fetches string value of URL user tried to navigate to while unauthenticated. - * @param options Defines the storage options for the URL; Defaults to session Storage. - * @returns route called prior to successful login. - */ - getDeepLinkRedirectUrl: (options?: StorageOptions) => Promise; - /** - * Store URL in session storage by default, but can be configured. Developed to handle - * unauthN interrupted navigation. - * @param url URL of route - * @param options Defines the storage options for the URL; Defaults to session Storage. - */ - setDeepLinkRedirectUrl: (url: string, options?: StorageOptions) => Promise; nextUpActiveUser: () => Promise; } diff --git a/libs/common/src/platform/models/domain/global-state.ts b/libs/common/src/platform/models/domain/global-state.ts index cb9e3f71b3..703a998d1c 100644 --- a/libs/common/src/platform/models/domain/global-state.ts +++ b/libs/common/src/platform/models/domain/global-state.ts @@ -4,5 +4,4 @@ export class GlobalState { vaultTimeoutAction?: string; enableBrowserIntegration?: boolean; enableBrowserIntegrationFingerprint?: boolean; - deepLinkRedirectUrl?: string; } diff --git a/libs/common/src/platform/services/state.service.ts b/libs/common/src/platform/services/state.service.ts index fb62af250b..a35659a7ac 100644 --- a/libs/common/src/platform/services/state.service.ts +++ b/libs/common/src/platform/services/state.service.ts @@ -1173,23 +1173,6 @@ export class StateService< ); } - async getDeepLinkRedirectUrl(options?: StorageOptions): Promise { - return ( - await this.getGlobals(this.reconcileOptions(options, await this.defaultOnDiskOptions())) - )?.deepLinkRedirectUrl; - } - - async setDeepLinkRedirectUrl(url: string, options?: StorageOptions): Promise { - const globals = await this.getGlobals( - this.reconcileOptions(options, await this.defaultOnDiskOptions()), - ); - globals.deepLinkRedirectUrl = url; - await this.saveGlobals( - globals, - this.reconcileOptions(options, await this.defaultOnDiskOptions()), - ); - } - protected async getGlobals(options: StorageOptions): Promise { let globals: TGlobalState; if (this.useMemory(options.storageLocation)) { diff --git a/libs/common/src/platform/state/state-definitions.ts b/libs/common/src/platform/state/state-definitions.ts index d50a3e6ac7..979321c1e3 100644 --- a/libs/common/src/platform/state/state-definitions.ts +++ b/libs/common/src/platform/state/state-definitions.ts @@ -38,6 +38,7 @@ export const BILLING_DISK = new StateDefinition("billing", "disk"); export const KEY_CONNECTOR_DISK = new StateDefinition("keyConnector", "disk"); export const ACCOUNT_MEMORY = new StateDefinition("account", "memory"); export const AVATAR_DISK = new StateDefinition("avatar", "disk", { web: "disk-local" }); +export const ROUTER_DISK = new StateDefinition("router", "disk"); export const LOGIN_EMAIL_DISK = new StateDefinition("loginEmail", "disk", { web: "disk-local", });