From 7bacec54ee08f047a24584f19983a5c4783cc7c1 Mon Sep 17 00:00:00 2001 From: mutugiii <mutugimutuma@gmail.com> Date: Thu, 9 Jan 2025 23:14:53 +0300 Subject: [PATCH] simple rbac for stronger health route protection --- src/app/home/home-router.module.ts | 4 ++-- src/app/shared/auth-guard.service.ts | 14 +++++++++----- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/app/home/home-router.module.ts b/src/app/home/home-router.module.ts index bf3a53ac97..28a7f2105f 100644 --- a/src/app/home/home-router.module.ts +++ b/src/app/home/home-router.module.ts @@ -34,8 +34,8 @@ const routes: Routes = [ { path: 'upgrade/myplanet', component: UpgradeComponent, data: { myPlanet: true } }, { path: 'teams', loadChildren: () => import('../teams/teams.module').then(m => m.TeamsModule) }, { path: 'enterprises', loadChildren: () => import('../teams/teams.module').then(m => m.TeamsModule), data: { mode: 'enterprise' } }, - { path: 'health', component: HealthListComponent }, - { path: 'health/profile/:id', loadChildren: () => import('../health/health.module').then(m => m.HealthModule) }, + { path: 'health', component: HealthListComponent, data: { roles: [ '_admin', 'health' ] } }, + { path: 'health/profile/:id', loadChildren: () => import('../health/health.module').then(m => m.HealthModule), data: { roles: [ '_admin', 'health' ] } }, { path: 'nation', component: TeamsViewComponent, data: { mode: 'services' } }, { path: 'earth', component: TeamsViewComponent, data: { mode: 'services' } }, { path: myDashboardRoute, component: DashboardComponent }, diff --git a/src/app/shared/auth-guard.service.ts b/src/app/shared/auth-guard.service.ts index 5461ff3422..91272411ab 100644 --- a/src/app/shared/auth-guard.service.ts +++ b/src/app/shared/auth-guard.service.ts @@ -22,12 +22,17 @@ export class AuthService { return this.pouchAuthService.getSessionInfo(); } - private checkUser(url: any): Observable<boolean> { + private checkUser(url: any, roles: any[]): Observable<boolean> { return this.getSession$().pipe( switchMap((sessionInfo) => { if (sessionInfo.userCtx.name) { // If user already matches one on the user service, do not make additional call to CouchDB - if (sessionInfo.userCtx.name === this.userService.get().name) { + const user = this.userService.get(); + if (sessionInfo.userCtx.name === user.name) { + if (roles.length > 0) { + const hasRole = roles.some(role => user.roles.includes(role)); + return hasRole ? of(true) : of(false); + } return of(true); } this.stateService.requestBaseData(); @@ -46,15 +51,14 @@ export class AuthService { // change if session has expired canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> { let currentRoute: ActivatedRouteSnapshot | null = route; - + const roles: Array<string> = currentRoute.data?.roles ?? []; while (currentRoute) { if (currentRoute.data && currentRoute.data.requiresAuth === false) { return of(true); } currentRoute = currentRoute.parent; } - - return this.checkUser(state.url); + return this.checkUser(state.url, roles); } // For login route will redirect to main app if there is an active session