Angular route user role

I have a guard to my route using roles , everytime the route is access … Read more Angular route user role

I have a guard to my route using roles , everytime the route is access I it calls the checkPermission with calls the and query getUserRoles which returns an array of roles.

The problem is that the getUserRoles is a bit heavy query , I don’t wanna call it everytime I access the route just to get the user list of roles.

What I want is only to call it once and then use the roles from that to access the routes , is there a cleaner way or how do we just call it once and then use it to access the routes , cause right now my code always calls or query the getUserRoles

#login code

  login() {
    this.showLoader();
        this.hasSubmit = true;
        this.apiErrMsg = null;
        const username = this.loginForm.controls['username'].value;
        const password = this.loginForm.controls['password'].value;
        let errMsg  = 'Unexpected error. Please contact your administrator.';
        this.authService
          .loginWithCredentials(username, password)
          .then((r: any) => {
            if (r.isSuccess) {
              console.log("r" , r)
              this.route.navigateByUrl('/');
            }else{                                         
              if(r.errors.length > 0){                
                if(r.errors[0].description.indexOf('not found') !== -1){
                  errMsg = ERR_FORM_MSG.INVALID_LOGIN;
                }
              }
              this.apiErrMsg = errMsg;              
            }
          })
          .catch((e): any => {
            this.apiErrMsg = e.message
              ? e.message
              : errMsg;
          })
          .finally(() => {
            this.hasSubmit = false;
            this.closeLoader();
          });
      }
  }

#auth guard code

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot } from '@angular/router';
import { AuthService } from '../services/auth.service';
import { Router } from '@angular/router';
import { Roles } from '../enums/enum-user-role.enum';


@Injectable({
  providedIn: 'root'
})

    export class AuthGuard implements CanActivate {
      userProfile: any;
     
      constructor(private authService: AuthService, private route: Router,) {}
    
      public async canActivate(route: ActivatedRouteSnapshot): Promise<boolean> {
        const allowedUserRoles = this.getRoutePermissions(route);
        return await this.checkPermission(allowedUserRoles);
      }
    
      private getRoutePermissions(route: ActivatedRouteSnapshot): Roles[] {
        if (route.data && route.data.userRoles) {
          return route.data.userRoles as Roles[];
        }
        return null;
      }
    
      private checkPermission(allowedUserRoles: Roles[]): Promise<boolean> {
        return this.authService.getSession().then((session: boolean) => {
          if (session) {
            if (!allowedUserRoles) {
              return true;   // if no user roles has been set, all user are allowed to access the route
            } else {
              return this.authService.getUserRoles().then((userRoles: string[]) => {
                if (this.authService.areUserRolesAllowed(userRoles, allowedUserRoles)) {
                  return true;
                } else {
                  this.route.navigateByUrl('/transactions');
                  return false;
                }
              });
            }
          } else { return false; }
        });
      }
    }

#app routing code

const routes: Routes = [
  {
    path: '',
    component: DashboardComponent,
    canActivate: [AuthGuard],
    children: [
      {
        path: 'properties',
        loadChildren: () => import('./features/property/property.module').then(m => m.PropertyModule),
        canActivate: [AuthGuard],
        data: {
          userRoles: [Roles.ADMIN, Roles.TRANSACTION_SUPER_USER, Roles.TRANSACTION_MANAGER]
        },
      },
      {
        path: 'settings',
        loadChildren: () => import('./features/settings/settings.module').then(m => m.SettingsModule),
        data: {
          title: 'Settings',
          userRoles: [Roles.ADMIN, Roles.TRANSACTION_SUPER_USER, Roles.TRANSACTION_MANAGER]
        }
      },
    ]
  },
  {
    path: 'login',
    component: LoginComponent,
  },
  {
    path: 'login/:authkey',
    component: LoginComponent,
  },
  {
    path: 'login/resetpassword/:authkey',
    component: LoginComponent,
  },
  {
    path:'**',
    redirectTo: ''    
  }
];
@NgModule({
  imports: [
    RouterModule.forRoot(routes, {
      useHash: true,
      preloadingStrategy: PreloadAllModules,
    }),
  ],
  exports: [RouterModule]
})
export class AppRoutingModule { }

#service for getting roles

public getUserRoles(item): Promise<string[]> {

    if (this.authUser === null) {
      this.setAuthUser()
    }

    return new Promise((resolve, reject) => {
      this.userService
      .getUserGeneralDetails(this.authUser.nameid , this.accountId = 0)
        .pipe(catchError((error: any, caught: any) => {
          reject(error);
          return caught;
        }),
          map((res: any) => res.data && res.data.userAccountDto
            .filter(account => account.accountName === res.data.associatedAccount)
            .map(account => account.userRoleDto.roleName)
          )).subscribe((role: string[]) => {
            resolve(role);
          });

    });
  }

Source: JavaSript – Stack Overflow



Leave a Reply

Your email address will not be published. Required fields are marked *