diff --git a/apps/web/src/app/core/core.module.ts b/apps/web/src/app/core/core.module.ts index 37ce80a826..842d31bb10 100644 --- a/apps/web/src/app/core/core.module.ts +++ b/apps/web/src/app/core/core.module.ts @@ -1,5 +1,6 @@ import { CommonModule } from "@angular/common"; import { APP_INITIALIZER, NgModule, Optional, SkipSelf } from "@angular/core"; +import { Router } from "@angular/router"; import { CollectionAdminService, @@ -175,7 +176,7 @@ const safeProviders: SafeProvider[] = [ safeProvider({ provide: EnvironmentService, useClass: WebEnvironmentService, - deps: [WINDOW, StateProvider, AccountService], + deps: [WINDOW, StateProvider, AccountService, Router], }), safeProvider({ provide: BiometricsService, diff --git a/apps/web/src/app/platform/web-environment.service.ts b/apps/web/src/app/platform/web-environment.service.ts index c2eb37eea5..9c2afff4a1 100644 --- a/apps/web/src/app/platform/web-environment.service.ts +++ b/apps/web/src/app/platform/web-environment.service.ts @@ -1,3 +1,4 @@ +import { Router } from "@angular/router"; import { ReplaySubject } from "rxjs"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; @@ -23,6 +24,7 @@ export class WebEnvironmentService extends DefaultEnvironmentService { private win: Window, stateProvider: StateProvider, accountService: AccountService, + private router: Router, ) { super(stateProvider, accountService); @@ -47,9 +49,34 @@ export class WebEnvironmentService extends DefaultEnvironmentService { this.environment$ = subject.asObservable(); } - // Web cannot set environment - async setEnvironment(region: Region, urls?: Urls): Promise { - return; + // Web setting env means navigating to a new location + setEnvironment(region: Region, urls?: Urls): Promise { + if (region === Region.SelfHosted) { + throw new Error("setEnvironment does not work in web for self-hosted."); + } + + const currentDomain = Utils.getDomain(this.win.location.href); + const currentRegion = this.availableRegions().find( + (r) => Utils.getDomain(r.urls.webVault) === currentDomain, + ); + + if (currentRegion.key === region) { + // They have selected the current region, nothing to do + return Promise.resolve(currentRegion.urls); + } + + const chosenRegion = this.availableRegions().find((r) => r.key === region); + + if (chosenRegion == null) { + throw new Error("The selected region is not known as an available region."); + } + + // Preserve the current in app route + params in the new location + const routeAndParams = `/#${this.router.url}`; + this.win.location.href = chosenRegion.urls.webVault + routeAndParams; + + // This return shouldn't matter as we are about to leave the current window + return Promise.resolve(chosenRegion.urls); } }