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