The application is resetting when the "$http" method accesses the initial ADAL "protected" URL for the first time

I have created a page inspired by the Angular SPA ADAL sample which can be found here

Upon returning from the Microsoft login page and accessing my API secured with AAD, the angular .config() function is called multiple times. This causes issues with updating the scope initially set in the app. However, after this initial conflict, everything functions as expected. Reloading the page does not replicate this issue, it only occurs the first time after logging in.

Is this normal behavior with ADAL? Is there a way to prevent this from happening? Am I incorrectly updating $scope from AJAX callbacks?

Here are some key code snippets:

app.js:

'use strict';
angular.module('app', ['ngRoute', 'AdalAngular'])
.config(['$routeProvider', '$httpProvider', 'adalAuthenticationServiceProvider', '$locationProvider', function ($routeProvider, $httpProvider, adalProvider, $locationProvider) {

$routeProvider.when("/visit", {
    controller: "visitCtrl",
    templateUrl: "/ngViews/Visit.html",
    requireADLogin: false,
}).when("/visit/:visitNumber", {
    controller: "visitCtrl",
    templateUrl: "/ngViews/Visit.html",
    requireADLogin: false,
}).when("/", {
    controller: "homeCtrl",
    templateUrl: "/ngViews/Home.html",
    requireADLogin: false,
}).when("/teamwork", {
    controller: "teamworkCtrl",
    templateUrl: "/ngViews/Teamwork.html",
    requireADLogin: false,
}).when("/mywork", {
    controller: "myWorkCtrl",
    templateUrl: "/ngViews/MyWork.html",
    requireADLogin: false,
}).when("/dashboard", {
    controller: "dashboardCtrl",
    templateUrl: "/ngViews/Dashboard.html",
    requireADLogin: false,
}).when("/error", {
    templateUrl: "/ngViews/Error.html",
    controller: "errorCtrl",
    requireADLogin: false,
});
$routeProvider.otherwise({ redirectTo: '/' }); // needed to avoid a bug in ADAL see: https://github.com/AzureAD/azure-activedirectory-library-for-js/issues/42


var endpoints = cmSettings.adalEndpoints;
//$locationProvider.html5Mode(true); // breaks ADAL
adalProvider.init(
    {
        instance: cmSettings.aadInstance,
        tenant: cmSettings.tenant,
        clientId: cmSettings.clientId,
        extraQueryParameter: 'nux=1',
        endpoints: endpoints,
        cacheLocation: 'localStorage', // enable this for IE, as sessionStorage does not work for localhost.  
        // Also, token acquisition for the To Go API will fail in IE when running on localhost, due to IE security restrictions.
    },
    $httpProvider
    );
}]);

controller:

'use strict'
angular.module('app')
.controller('navBarCtrl',   ['$scope', '$location', 'visitsSvc', '$timeout',    function ($scope, $location, visitsSvc, $timeout) {
$scope.myWorkCount = 0;
$scope.teamworkCount = 0;
$scope.loading = false;

var updateVisitCount = function () {
    $scope.loading = true;
    $scope.$on("cm:myVisitsReceived", function (event, args) {
        $timeout(function () {
            if (args.data) {
                $scope.myWorkCount = args.data.length;
            }
            $scope.loading = false;
        });
    });

    $scope.$on("cm:teamVisitsReceived", function (event, args) {
        $timeout(function () {
            if (args.data) {
                $scope.teamworkCount = args.data.length;
            }
            $scope.loading = false;
        });
    });

    visitsSvc.getMyVisits();
    visitsSvc.getTeamVisits();
}

if ($scope.userInfo.isAuthenticated && !$scope.loading) {
    updateVisitCount();
} else {
    $scope.$on("adal:loginSuccess", function (scope) {
        updateVisitCount();
    });
}
}]);

data service:

angular.module('app')
.factory('visitsSvc', ['$http', '$rootScope', function ($http, $rootScope) {



    $http.defaults.useXDomain = true;
    delete $http.defaults.headers.common['X-Requested-With'];

    return {
        getMyVisits: function () {
            $http.get(cmSettings.apiUrl + '/api/v1/visits/my').success(function (data, status, headers, config) {
                $rootScope.$broadcast("cm:myVisitsReceived", { data: data, status: status, success: true });
            })
           .error(function (data, status, headers, config) {
               $rootScope.$broadcast("cm:myVisitsReceived", { data: data, status: status, success: false });
           });
        },
        getTeamVisits: function () {
            $http.get(cmSettings.apiUrl + '/api/v1/visits/team').success(function (data, status, headers, config) {
                $rootScope.$broadcast("cm:teamVisitsReceived", { data: data, status: status, success: true });
            })
           .error(function (data, status, headers, config) {
               $rootScope.$broadcast("cm:teamVisitsReceived", { data: data, status: status, success: false });
           });
        },
        getVisit: function (visitNumber) {
            $http.get(cmSettings.apiUrl + '/api/v1/visits/' + visitNumber).success(function (data, status, headers, config) {
                $rootScope.$broadcast("cm:visitsReceived", { data: data, status: status, success: true });
            })
           .error(function (data, status, headers, config) {
               $rootScope.$broadcast("cm:visitsReceived", { data: data, status: status, success: false });
           });;
        },
        search: function (searchTerms) {
            return $http.get(cmSettings.apiUrl + '/api/v1/visits/search/' + searchTerms).success(function (data, status, headers, config) {
                $rootScope.$broadcast("cm:searchVisitsReceived", { data: data, status: status, success: true });
            })
           .error(function (data, status, headers, config) {
               $rootScope.$broadcast("cm:searchVisitsReceived", { data: data, status: status, success: false });
           });
        },
    };
}])

console output:

DOM7011: The code on this page disabled back and forward caching. For more information, see: http://go.microsoft.com/fwlink/?LinkID=291337
File: authorize
HTML1300: Navigation occurred.
File: login
HTML1200: microsoftonline.com is on the Internet Explorer Compatibility View List ('C:\Users\Micah\AppData\Local\Microsoft\Internet Explorer\IECompatData\iecompatdata.xml').
File: login
DOM7011: The code on this page disabled back and forward caching. For more information, see: http://go.microsoft.com/fwlink/?LinkID=291337
File: authorize
HTML1506: Unexpected token.
File: localhost:44300, Line: 115, Column: 1
The returned id_token is not parseable.
The returned id_token is not parseable.
State: 0edacc1d-a253-42ac-8a1d-cf1206ad3beb
State status:true
State is right
renewToken is called for resource:https://cloudmedIdentity.onmicrosoft.com/dataApi
Add adal frame to document:adalRenewFramehttps://cloudmedIdentity.onmicrosoft.com/dataApi
...
(replace with your own unique content)
...
Fragment has access token

Answer №1

To secure specific routes, simply assign AzureAD:true to those routes. Adal will automatically initiate the login process and redirect to the protected route upon successful authentication. Once the page has loaded, you can access webapi methods without needing a loginSuccess event.

Are you experiencing multiple instances of the loginSuccess event being triggered in your configuration?

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

What is the best way to send JavaScript data to PHP?

Is it possible to post a variable to a PHP script without refreshing the page? If so, how can this be achieved? Here is an example using jQuery: $.ajax({ url: "myphpfile.php", type: "post", data: json/array/whatever, success: function(){ ...

Maintain the tab count in AngularJs navigation

As someone who is new to AngularJs, I am currently exploring the best approach for a tabController to remember the last clicked tab when transitioning to a new controller. Imagine having 3 tabs and clicking on tab 3; then navigating to a new controller and ...

Checking the existence of a user's email in Node.js

Hey there! I am new here and currently learning Node.js with Express. I'm trying to find a way to check if a user's email already exists in the database. Here is what I have so far: const emailExists = user.findOne({ email: req.body.email }); if ...

Tips on passing a variable and API response to the following promise in JavaScript!

Using the initial promise "crypto.model.find()" allows me to store an array of "symbols" ( symbol[] ) from the database and retrieve some IDs that I will utilize to construct a URL for making a request to an API using axios.get(url). Upon receiving a resp ...

How can a function in one React component be invoked from another component?

Currently in my React project's App.js, I am calling the this.searchVenues() function in my return statement. It works, but the implementation is messy and I know there must be a more efficient way to achieve this. The searchVenues() function is locat ...

Can you explain how to use a toggle switch to make a select dropdown select a random option?

Currently, I am in the process of setting up a page for a character generator. Users will have the option to randomize traits or input their own. The interface includes toggle switches for the "choice vs random" options for each trait category, as well as ...

What methods can be used by the client-side to determine whether a file has been successfully downloaded or received from

When a client-side file download request is initiated, I dynamically create a form element with hidden attributes and submit it to the server via POST. During this process, I need to display a loading spinner that will be hidden once the download is comple ...

Keep the user on the current page even after submitting the parameter

I have a situation where I am loading a page into a specific div. This loaded page contains a link that includes a parameter which directs to another page for deletion. However, when I click on the loaded page within the div, it redirects me to the deletio ...

The specified type '{ state: any; dispatch: React.Dispatch<{ type: string; value: any; }>; }' is not compatible with the expected type

I've been working on a UI layout that includes checkboxes on the left, a data table on the right, and a drop zone box. The aim is to keep the table data updated whenever a new file is dropped, and also filter the data based on checkbox selection. I ma ...

What went awry with my Angular form implementation?

I am new to using angular forms and I am attempting to validate an email field, displaying a message if the input is invalid. Although I thought I had done everything correctly, the error message is not appearing. <form name="Login" novalidate> ...

React-Native Error: Invalid element type detected

While attempting to run my React Native app on my iPhone using Expo, I encountered an error displayed in a red background area. Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite ...

What is the best way to display a component with multiple pieces of content?

I have a tool that generates card components, extracting data from a const array and displaying it in a table format within a card UI component. I am looking to add an ADD button inside each card to open a modal with input fields. However, the issue is tha ...

The presence of parentheses in a JQuery selector

My database contains divs with ids that sometimes have parentheses in them. This is causing issues with my JQuery selector. How can I resolve this problem? Let me provide an example to illustrate: https://jsfiddle.net/2uL7s3ts/1/ var element = 'hel ...

How to programmatically clear an input field in Angular using Bootstrap's typeahead feature

My current setup involves utilizing a form to populate a list displayed alongside the form. The markup looks like: <form name="stateForm"> <input type="text" ng-model="model.name" typeahead="state for state in states | filter:$viewValue"> ...

Using AngularJS to facilitate payments through PayPal

Hello there, I am new to AngularJS and I am trying to convert this cURL request into AngularJS. Can someone help me with that? curl https://api-3t.sandbox.paypal.com/nvp --insecure \ -d METHOD=name \ -d VERSION=XX.0 \ -d USER=API-Us ...

Basic AngularJS executing on JSFiddle

Can someone help me create a jsfiddle with the code below: <html> <head> </head> <body> <div ng-app ng-controller="MainCtrl"> <ul> <li ng-repeat="num in nums"> {{num}} ...

How can I parse JSON in React using the Parse function?

I am currently working with three list components, and when I click on any item in the tree list, it displays the JSON data. However, I would prefer to view it in a parse format rather than JSON. I attempted to use let json = JSON.parse(this.props.node, n ...

Ramda represents a distinct alternative to traditional vanilla JavaScript

I'm feeling a bit confused about how Ramda really works. I found this code and I'm not entirely sure how it functions. const render = curry( (renderer, value) => is(Function, renderer) && renderer(value) ); I just need to grasp an ...

Guide on incorporating pinching gestures for zooming in and out using JavaScript

I have been working on implementing pinch zoom in and out functionality in JavaScript. I have made progress by figuring out how to detect these gestures using touch events. var dist1=0; function start(ev) { if (ev.targetTouches.length == 2) {//checkin ...

Error: The property 'initializeApp' cannot be read because it is undefined

Recently, I decided to integrate Firebase libraries into my Vue project by installing them using npm install firebase. I then proceeded to add these Firebase libraries in my main.js file: import { Firebase } from 'firebase/app' import 'fir ...