4

I have a lot of trusts in my website, so to make secure routes I build the next guard:

export class TrustGuard implements CanActivate {
    constructor(private router: Router) {
    }

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        return /*Check if user has the trust or not*/;
    }
}

So, in the routes I will can add the guard like canActivate: [TrustGuard]

The problem is that I have too many trusts, consequently I would need to build one guard for each trust. So I'm trying to build a factory of guards that to avoid to implements too many similar guards.

My target is to find the way of set the route like canActivate: [FactoryTrustGuard(Trust.seeDashboard)]

Is it that possible?

Georgevik
  • 539
  • 1
  • 5
  • 18
  • Does this answer your question? [How to pass parameters to constructor of canActivate?](https://stackoverflow.com/questions/50624086/how-to-pass-parameters-to-constructor-of-canactivate) – Valentin Bossi Dec 29 '22 at 16:27

1 Answers1

7

This will likely create problems with AOT, because route definitions are supposed to be static.

The guards can DRYed up to eliminate most boilerplate code:

export abstract class TrustGuard  {
    protected abstract trust: string;

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        /* check against this.trust */
    }
}

export class FooTrustGuard extends TrustGuard {
    protected trust = Trust.foo;
}

If there are tens of similar guards, it is possible to make it a single guard and pass a role through route data:

export class TrustGuard  {
    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        const trust = route.data['trust'];
        if (trust in Trust) {
          ...
        } else {
          throw ...;
        }
    }
}

And use it like

{ route: ..., canActivate: [TrustGuard], data: { trust: Trust.seeDashboard } }
Estus Flask
  • 206,104
  • 70
  • 425
  • 565