Search code examples
node.jsangulartypescriptnpmangular2-routing

Angular auth guard not redirecting when returning Promise<UrlTree>


I have created an auth guard for my /sign-in and /verify-email routes to only allow access to the users that are not logged in or havent verified their email:


export const signInGuard: CanActivateFn = (activatedRouteSnapshot: ActivatedRouteSnapshot): Promise<UrlTree | boolean> => {
  const router = inject(Router);
  const authenticationService = inject(AuthenticationService);

  const routeToResolve = activatedRouteSnapshot.url[0].path;

  console.log(routeToResolve)

  return firstValueFrom(authenticationService.onAuthStateChanged$)
    .then(user => {
      if (routeToResolve === 'verify-email') {
        if (!user) {
          return router.parseUrl('/sign-in');  // ### the issue is here ###
        } else if (user.emailVerified) {
          return router.parseUrl('/');
        } else {
          return true;
        }
      } else {
        if (user) {
          return router.parseUrl('/');
        } else {
          return true;
        }
      }
    });
};

The log from the console when logging the routeToResolve variable:


sign-in.guard.ts:12 verify-email
user.service.ts:21 [User Service]
user.service.ts:22 null
sign-in.guard.ts:12 sign-in

The guard works fine for all cases except for when the user is null and they are trying to access /verify-email. My expected behavior was to redirect the user in this case to /sign-in. Instead of this behavior, the user stays on the same route (/verify-email) with a blank white screen.

When I replace return router.parseUrl('/sign-in') with return router.parseUrl('/'), the user is correctly redirected, which tells me that the logic is executed correctly. But when i use return router.parseUrl('/sign-in'), it does not work.

I have also tried replacing that line of the code with:

return router.navigateByUrl('/sign-in').then(() => false);

Which still resulted in the same buggy behavior.


Solution

  • White page usually means that guard is hung up, due to some observable not emitting/completing. From logs it seems that you're redirected from 'verify-email' to 'sign-in' route, then this guards is checked again, but doesn't let you throught. Any chance that authenticationService.onAuthStateChanged$ doesn't emit any value the second time, and you're just hung up on it?

    If not, maybe there's some other guard on 'sign-in' route that doesn't work well?

    You could add a console log inside .then block, it would give you more information on what's happening