diff --git a/apps/web/src/app/oss-routing.module.ts b/apps/web/src/app/oss-routing.module.ts index 83f2f7d188f..8b7ddb07eae 100644 --- a/apps/web/src/app/oss-routing.module.ts +++ b/apps/web/src/app/oss-routing.module.ts @@ -13,6 +13,7 @@ import { import { ChangePasswordComponent } from "@bitwarden/angular/auth/password-management/change-password"; import { SetInitialPasswordComponent } from "@bitwarden/angular/auth/password-management/set-initial-password/set-initial-password.component"; import { canAccessFeature } from "@bitwarden/angular/platform/guard/feature-flag.guard"; +import { preventProdAccessGuard } from "@bitwarden/angular/platform/guard/prevent-prod-access.guard"; import { PasswordHintComponent, RegistrationFinishComponent, @@ -176,11 +177,9 @@ const routes: Routes = [ path: "", component: AnonLayoutWrapperComponent, children: [ - // TODO: consider adding guard to prevent access to this route if env is not dev or qa. - // TODO: figure out why this doesn't work when other one does. - // this is for anon-web scenario { path: "feature-flags", + canMatch: [preventProdAccessGuard], data: { pageTitle: { key: "featureFlags", @@ -716,10 +715,10 @@ const routes: Routes = [ component: SponsoredFamiliesComponent, data: { titleId: "sponsoredFamilies" } satisfies RouteDataProperties, }, - // TODO: consider adding guard to prevent access to this route if env is not dev or qa. { path: "developer-tools", data: { titleId: "developerTools" } satisfies RouteDataProperties, + canMatch: [preventProdAccessGuard], loadComponent: () => import("./platform/settings/developer-tools").then((m) => m.DeveloperToolsComponent), children: [ diff --git a/libs/angular/src/platform/guard/prevent-prod-access.guard.spec.ts b/libs/angular/src/platform/guard/prevent-prod-access.guard.spec.ts new file mode 100644 index 00000000000..267b11f2aea --- /dev/null +++ b/libs/angular/src/platform/guard/prevent-prod-access.guard.spec.ts @@ -0,0 +1 @@ +// TODO: add tests for this guard diff --git a/libs/angular/src/platform/guard/prevent-prod-access.guard.ts b/libs/angular/src/platform/guard/prevent-prod-access.guard.ts new file mode 100644 index 00000000000..f01f6d4f276 --- /dev/null +++ b/libs/angular/src/platform/guard/prevent-prod-access.guard.ts @@ -0,0 +1,26 @@ +import { inject } from "@angular/core"; +import { CanMatchFn } from "@angular/router"; +import { firstValueFrom } from "rxjs"; + +import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; +import { PRODUCTION_REGIONS } from "@bitwarden/common/platform/services/default-environment.service"; + +/** + * Guard to prevent matching routes in production environments. + * Allows for developer tooling that should only be accessible in non-production environments. + */ +export const preventProdAccessGuard: CanMatchFn = async (): Promise => { + const environmentService = inject(EnvironmentService); + + const environment = await firstValueFrom(environmentService.environment$); + + const region = environment.getRegion(); + + const prodRegions = PRODUCTION_REGIONS.map((regionConfig) => regionConfig.key); + + if (prodRegions.includes(region)) { + return false; + } + + return true; +};