[SM-673] redirect from SM root to overview page (#5202)

* remove deprecated CanActivate; use CanActivateFn; redirect to available org from SM root

* fix route

* not working: redirect after login

* add sync service workaround
This commit is contained in:
Will Martin 2023-05-05 14:48:12 -04:00 committed by GitHub
parent d8b8bf5218
commit 53c81a2ee3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 96 additions and 55 deletions

View File

@ -5,10 +5,8 @@ import { SharedModule } from "@bitwarden/web-vault/app/shared";
import { LayoutModule } from "./layout/layout.module";
import { SecretsManagerSharedModule } from "./shared/sm-shared.module";
import { SecretsManagerRoutingModule } from "./sm-routing.module";
import { SMGuard } from "./sm.guard";
@NgModule({
imports: [SharedModule, SecretsManagerSharedModule, SecretsManagerRoutingModule, LayoutModule],
providers: [SMGuard],
})
export class SecretsManagerModule {}

View File

@ -13,59 +13,70 @@ import { ProjectsModule } from "./projects/projects.module";
import { SecretsModule } from "./secrets/secrets.module";
import { ServiceAccountsModule } from "./service-accounts/service-accounts.module";
import { SettingsModule } from "./settings/settings.module";
import { SMGuard } from "./sm.guard";
import { canActivateSM } from "./sm.guard";
import { TrashModule } from "./trash/trash.module";
const routes: Routes = [
buildFlaggedRoute("secretsManager", {
path: ":organizationId",
component: LayoutComponent,
canActivate: [AuthGuard, OrganizationPermissionsGuard, SMGuard],
data: {
organizationPermissions: (org: Organization) => org.canAccessSecretsManager,
},
path: "",
children: [
{
path: "",
component: NavigationComponent,
outlet: "sidebar",
},
{
path: "secrets",
loadChildren: () => SecretsModule,
data: {
titleId: "secrets",
},
},
{
path: "projects",
loadChildren: () => ProjectsModule,
data: {
titleId: "projects",
},
},
{
path: "service-accounts",
loadChildren: () => ServiceAccountsModule,
data: {
titleId: "serviceAccounts",
},
},
{
path: "trash",
loadChildren: () => TrashModule,
data: {
titleId: "trash",
},
},
{
path: "settings",
loadChildren: () => SettingsModule,
},
{
path: "",
loadChildren: () => OverviewModule,
canActivate: [canActivateSM],
pathMatch: "full",
children: [],
},
{
path: ":organizationId",
component: LayoutComponent,
canActivate: [AuthGuard, OrganizationPermissionsGuard],
data: {
organizationPermissions: (org: Organization) => org.canAccessSecretsManager,
},
children: [
{
path: "",
component: NavigationComponent,
outlet: "sidebar",
},
{
path: "secrets",
loadChildren: () => SecretsModule,
data: {
titleId: "secrets",
},
},
{
path: "projects",
loadChildren: () => ProjectsModule,
data: {
titleId: "projects",
},
},
{
path: "service-accounts",
loadChildren: () => ServiceAccountsModule,
data: {
titleId: "serviceAccounts",
},
},
{
path: "trash",
loadChildren: () => TrashModule,
data: {
titleId: "trash",
},
},
{
path: "settings",
loadChildren: () => SettingsModule,
},
{
path: "",
loadChildren: () => OverviewModule,
pathMatch: "full",
},
],
},
],
}),

View File

@ -1,10 +1,42 @@
import { Injectable } from "@angular/core";
import { ActivatedRouteSnapshot, CanActivate } from "@angular/router";
import { inject } from "@angular/core";
import {
ActivatedRouteSnapshot,
CanActivateFn,
createUrlTreeFromSnapshot,
RouterStateSnapshot,
} from "@angular/router";
@Injectable()
export class SMGuard implements CanActivate {
async canActivate(route: ActivatedRouteSnapshot) {
// TODO: Verify org
return true;
import { AuthGuard } from "@bitwarden/angular/auth/guards/auth.guard";
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
/**
* Redirects from root `/sm` to first organization with access to SM
*/
export const canActivateSM: CanActivateFn = async (
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
) => {
const syncService = inject(SyncService);
const authService = inject(AuthService);
const orgService = inject(OrganizationService);
const authGuard = inject(AuthGuard);
/** Workaround to avoid service initialization race condition. */
if ((await syncService.getLastSync()) == null) {
await syncService.fullSync(false);
}
}
if ((await authService.getAuthStatus()) !== AuthenticationStatus.Unlocked) {
return authGuard.canActivate(route, state);
}
const orgs = await orgService.getAll();
const smOrg = orgs.find((o) => o.canAccessSecretsManager);
if (smOrg) {
return createUrlTreeFromSnapshot(route, ["/sm", smOrg.id]);
}
return createUrlTreeFromSnapshot(route, ["/vault"]);
};