1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-10-09 05:57:40 +02:00
bitwarden-browser/apps/web/src/app/core/router.service.ts
rr-bw f79d159277
[PM-5500] Implement StateProvider in RouterService (#8119)
* implement StateProvider in RouterService

* Remove 'export'

Co-authored-by: Andreas Coroiu <acoroiu@bitwarden.com>

* Skip parameter

Co-authored-by: Andreas Coroiu <acoroiu@bitwarden.com>

---------

Co-authored-by: Andreas Coroiu <acoroiu@bitwarden.com>
2024-04-02 10:16:42 -07:00

106 lines
3.1 KiB
TypeScript

import { Injectable } from "@angular/core";
import { Title } from "@angular/platform-browser";
import { ActivatedRoute, NavigationEnd, Router } from "@angular/router";
import { filter, firstValueFrom } from "rxjs";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.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<string>;
private previousUrl: string = undefined;
private currentUrl: string = undefined;
constructor(
private router: Router,
private activatedRoute: ActivatedRoute,
private titleService: Title,
private stateProvider: StateProvider,
i18nService: I18nService,
) {
this.deepLinkRedirectUrlState = this.stateProvider.getGlobal(DEEP_LINK_REDIRECT_URL);
this.currentUrl = this.router.url;
router.events
.pipe(filter((e) => e instanceof NavigationEnd))
.subscribe((event: NavigationEnd) => {
this.currentUrl = event.url;
let title = i18nService.t("bitWebVault");
if (this.currentUrl.includes("/sm/")) {
title = i18nService.t("bitSecretsManager");
}
let child = this.activatedRoute.firstChild;
while (child.firstChild) {
child = child.firstChild;
}
const titleId: string = child?.snapshot?.data?.titleId;
const rawTitle: string = child?.snapshot?.data?.title;
const updateUrl = !child?.snapshot?.data?.doNotSaveUrl ?? true;
if (titleId != null || rawTitle != null) {
const newTitle = rawTitle != null ? rawTitle : i18nService.t(titleId);
if (newTitle != null && newTitle !== "") {
title = newTitle + " | " + title;
}
}
this.titleService.setTitle(title);
if (updateUrl) {
this.setPreviousUrl(this.currentUrl);
}
});
}
getPreviousUrl(): string | undefined {
return this.previousUrl;
}
setPreviousUrl(url: string): void {
this.previousUrl = url;
}
/**
* Save URL to Global State. This service is used during the login process
* @param url URL being saved to the Global State
*/
async persistLoginRedirectUrl(url: string): Promise<void> {
await this.deepLinkRedirectUrlState.update(() => url);
}
/**
* Fetch and clear persisted LoginRedirectUrl if present in state
*/
async getAndClearLoginRedirectUrl(): Promise<string> | undefined {
const persistedPreLoginUrl = await firstValueFrom(this.deepLinkRedirectUrlState.state$);
if (!Utils.isNullOrEmpty(persistedPreLoginUrl)) {
await this.persistLoginRedirectUrl(null);
return persistedPreLoginUrl;
}
return;
}
}