Angular Application caught in an infinite loop

Currently, I have an Angular web application that utilizes the @microsoft/microsoft-graph-client to fetch the logged-in user's details. The user is signed in using @azure/msal-angular. In order to log the user in, I have an authentication service that includes the following code:

  async signIn(): Promise<void> {
    const result = await this.msalService.loginPopup(OAuthSettings.consentScopes)
      .catch((reason) => {
        this.alertsService.add('Login failed', JSON.stringify(reason, null, 2));
      });

    if (result) {
      this.authenticated = true;
      await this.getUser();
    }
  }
  private async getClient(): Promise<Client> {
    const graphClient = Client.init({
      // Initialize the Graph client with an auth
      // provider that requests the token from the
      // auth service
      authProvider: async (done) => {
        const token = await this.getAccessToken()
          .catch((reason) => {
            done(reason, null);
          });
        if (token) {
          done(null, token);
        } else {
          done('Could not get an access token', null);
        }
      }
    });
    return graphClient;
  }

private async getUser() {
    if (!this.authenticated) {
      return null;
    }
    const graphClient = await this.getClient();

    // Get the user from Graph (GET /me)
    const graphUser = await graphClient.api('/me').get();

    console.log('USERNAME: ', graphUser.displayName);
    sessionStorage.setItem('d365dataportal.user', graphUser);
    if (graphUser.mail != null) {
      sessionStorage.setItem('d365dataportal.user.email', graphUser.mail);
    } else {
      sessionStorage.setItem('d365dataportal.user.email', graphUser.userPrincipalName);
    }
    sessionStorage.setItem('d365dataportal.user.avatar', graphUser.avatar);
    sessionStorage.setItem('d365dataportal.user.name', graphUser.displayName);
  }

This is how my OAuthSettings are defined:

export const OAuthSettings = {
  appId: 'App GUID from Azure Here',
  redirectUri: 'http://localhost:4200',
  consentScopes: ['user.read',
    'Directory.Read.All',
    'Directory.ReadWrite.All',
    'Directory.AccessAsUser.All']
};

The issue I am encountering is related to the application hanging when this.msalService.loginPopup() is triggered. The popup window remains open indefinitely and fails to authenticate or redirect back to my page. I am uncertain as to why this is transpiring. Any assistance in pinpointing any potential errors would be greatly appreciated.

UPDATE

The previous details were retained as my original inquiry. Upon further investigation, I have determined that the problem is unrelated to the initial query. Therefore, I have updated the title of my question.

Answer №1

After troubleshooting, I discovered that the issue I was facing was not related to Azure AD or Graph API. The problem lay within my component HTML, where an *ngIf directive was dependent on the result of a function. This is what the code snippet looked like:

<a mat-list-item *ngIf="authService.functionThatReturnsBoolean()" [routerLink]="['/SomeRoute']" routerLinkActive="router-link-active">Link Name</a>

Instead of this setup, I decided to update my service to store the results in a property and modify the *ngIf directive to reference that property like so:

<a mat-list-item *ngIf="authService.booleanProperty" [routerLink]="['/SomeRoute']" routerLinkActive="router-link-active">Link Name</a>

The issue stemmed from Angular continuously checking for the status in the *ngIf condition, causing what seemed like an infinite loop that eventually led to Chrome crashing.

Answer №2

After investigating the MSAL library, I've come across a potential issue or feature that I'm not fully grasping. Within the UserAgentApplication.js file, there is a function called loginPopupHelper();

Upon closer inspection of the success callback function for

this.authorityInstance.ResolveEndpointsAsync()
, I noticed a specific if block:

if (popUpWindow) {
    _this._logger.infoPii("Navigated Popup window to:" + urlNavigate);
    popUpWindow.location.href = urlNavigate;
}

This code snippet clearly redirects the popup window to a specified URL without closing it, unlike the fail callback. My temporary solution was to modify it as follows:

if (popUpWindow) {
    _this._logger.infoPii("Navigated Popup window to:" + urlNavigate);
    window.location.href = urlNavigate;
    popUpWindow.close();
}

However, this fix may not be stable in the long run as it could potentially be overwritten with library updates. Additionally, this modification changes the behavior from a popup to a redirect to the MS login page and back after providing credentials. I have some insights into why this occurs, but I currently lack the time to delve deeper. I may initiate a discussion about this on Github if it hasn't been done already.

That's the extent of my findings for now.

UPDATE: It appears that similar issues have been raised on Github. Links to relevant discussions include:

https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/545

https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/479

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Angular is incorrectly updating all fields at once instead of updating only the intended one field

I am facing an issue with my *ngFor loop where I am attempting to update a number field on click, but it ends up updating all the items with the same value. Here is a snippet of my HTML: <form *ngFor="let product of products" [formGroup]=&quo ...

Ways to adjust the ngx-pagination color scheme?

I am looking to customize the background color of ngx-pagination Here is my current code: <pagination-controls class="custom-pagination" id="indicadorPaginationResults" (pageChange)="p=$event" maxSize="9" directionLinks="true" autoHide="true" previ ...

Setting up pagination in Angular Material can sometimes present challenges

After implementing pagination and following the guidelines provided here. This is my code from the app.component.ts file - import { Component, OnInit, ViewChild } from '@angular/core'; import {MatPaginator} from '@angular/material/paginat ...

Is it possible to eliminate the table borders and incorporate different colors for every other row?

Eliminating the table borders and applying color to alternate rows. Check out my code snippet: https://stackblitz.com/angular/dnbermjydavk?file=app%2Ftable-overview-example.ts. ...

Why is it necessary to omit node_modules from webpack configuration?

Check out this webpack configuration file: module.exports = { mode: "development", entry: "./src/index.ts", output: { filename: "bundle.js" }, resolve: { extensions: [".ts"] }, module: { rules: [ { test: /\.ts/ ...

Having trouble authenticating with Google using Angular, Express, and Passport due to a 'No 'Access-Control-Allow-Origin' error?

Scenario In my development project, I'm constructing a stateless application utilizing Angular, Express, and PassportJS for user authentication via Google accounts. The aim is to implement JWT tokens to maintain the application's statelessness. ...

Guide for specifying type when passing a component as a prop

Struggling to successfully pass a component as a prop to a straightforward functional component called RenderRoute: interface RouteProps { component: React.ComponentType; isProtected: boolean; isLoggedIn: boolean; path?: string; exact?: boolean; ...

Angular 10 - unable to bind 'formGroup' as it is not recognized as a valid property of 'form'

In my existing Angular application, I need to implement routing and a login page as the functionality expands. To integrate routing, I have included the following code: app.module.ts // Importing various modules @NgModule({ declarations: [ App ...

Linking Two HTML Components in Angular 4 with Identical Values

Recently, I've started working with Angular and encountered an issue. In a table row, the value item.md_id is bound like this: <tr *ngFor="let item of driverData"> <td class="align-right" id="md_id" [(ngModel)]="item.md_id" name="driverId ...

Switching Angular repository to download node_modules dependencies from internal company source: A step-by-step guide

Within my company, we have an internal artifactory where all the dependency libraries must be sourced from. It is not possible for me to download them from the internet using 'npm install'. Upon examining the package-lock.json file, I noticed th ...

Is it possible to utilize multiple useMutation hooks within a single component?

I'm curious about how to utilize multiple mutations in a component effectively. For instance, if I need to both create and update the same component, how can I achieve this? Here's an example: const [createUser, {data}] = useMutation(CREATE_US ...

Tips for choosing a specific quantity and adjusting its value

Just starting out with Ionic 3 and looking for some help with the code. Can anyone assist me in understanding how to change the value of an item in a shopping cart and have the subtotal reflect that change? cart.ts private _values1 = [" 1 ", "2", " 3 "," ...

What is the best way to transform a JavaScript object into a chain of interconnected links?

My goal is to transform an object structure like the one below... var obj1 = { firstName: 'John', lastName: 'Green', car: { make: 'Honda', model: 'Civic', revisions: [ { miles: 10150, code: & ...

How can JSON be best connected in Angular for optimal performance?

My JSON structure is as follows: { items:[], errors:[], foundItems:9 } One part of my program requires access to "items", while another part needs access to "errors." To resolve this issue, I decided to create a new interface and a new class to hand ...

The issue encountered is a TypeError stating that it is unable to retrieve properties of an undefined value, specifically in relation to the 'imageUrl

When I include the following line of HTML code: <td> <img align="center" [src]="productByBarCode.imageUrl" /> </td> An error is thrown by the console: ERROR TypeError: Cannot read properties of undefined (reading &a ...

What is the proper way to utilize a function in C# that integrates with a window form using TypeScript?

I am currently working on a code that is in c# and utilizes a web browser. My goal is to convert the existing JavaScript code to Angular 7 and Typescript. Below is the c# code and the corresponding JavaScript code used to access the c# function from JavaS ...

Single sign-on (SSO) functionality experiencing issues when attempting to embed a Tableau link within an iframe

I have developed an application using Angular 4 and I am attempting to embed Tableau dashboards within the application. The embedded Tableau dashboard is asking for sign-in credentials. <iframe src="https://tableauserver/view/dashboard/12345" sandbox= ...

Encountering an issue with Angular 5.2 application build on VSTS build server: Running into "CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory" error

Out of nowhere, the builds began failing with the following error : 2019-01-03T12:57:22.2223175Z EXEC : FATAL error : CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory error MSB3073: The command "node node_modules/webpack/bin/w ...

How to implement an instance method within a Typescript class for a Node.js application

I am encountering an issue with a callback function in my Typescript project. The problem arises when I try to implement the same functionality in a Node project using Typescript. It seems that when referencing 'this' in Node, it no longer points ...

What is the method in Angular 6 that allows Observable to retrieve data from an Array?

What is the method to retrieve data of an Array using Observable in Angular 6? ob: Observable<any> array = ['a','b','c'] this.ob.subscribe(data => console.log(data)); ...