Search code examples
angularaws-amplifyauthenticator

The AuthenticatorService status is `configuring` when evalutating canActivate


I want to protect part of my angular application with a route guard, my route structure is therefore as follows:

export const ROUTES: Routes = [
  {
    path: '',
    component: FirmSignup2Component,
    children: [
      {
        path: 'user-or-admin',
        component: UserOrAdminComponent,
        children: [
          {
            path: 'user',
            component: UserComponent,
          },
          {
            path: 'admin',
            component: AdminComponent,
          },
        ],
      },
      {
        path: 'secure',
        component: SecureComponent,
        canActivate: [
          () => {
            console.log(inject(AuthenticatorService).authStatus);
            return inject(AuthenticatorService).authStatus === 'authenticated';
          },
        ],
        children: [
          {
            path: 'page1',
            component: Page1Component,
          },
          {
            path: 'page2',
            component: Page2Component,
          },
        ],
      },
    ],
  },
]

Where '/secure' and its child routes require authentication through either the user or admin components. I don't want to replicate the entire subtree of secure under each of the login components, so I create a separate part of the routes of login as opposed to wrapping '/secure' with the <amplify-authenticator /> component.

However, when I evaluate the authStatus in canActivate it is always 'configuring'. Once the view has loaded it is authorised. What's happening? How can I use an Auth guard with the Amplify Angular Authenticator?


Solution

  • The workaround that I have is to assess the authentication status only on lazy-loaded routes:

    app.routes.ts

    ...
    {
        path: 'private',
        loadChildren: () => import('./private/private.routes').then((m) => m.routes),
        canActivate: [MyAuthGuard],
      },
    ...
    

    And then in MyAuthGuard we can access the auth status

    ...
    export const MyAuthGuard: CanActivateFn = async (route, state) => {
      return inject(AuthenticatorService).authStatus == 'authenticated';
    };
    ...
    

    Note that we seem to need to inject the AuthenticatorService in the top-level component for this to work

    app.component.ts

    ...
    export class AppComponent {
      constructor(
    public authenticatorService: AuthenticatorService,
    ...