I am using Microsoft Login in my Angular application and below is my version of Angular and Node.JS installed
Angular CLI: 16.2.14
Node: 18.17.1
I have created a module name “Home” in which all the other modules are imported and I have imported Home Module in my App Module. So I have written the MSAL Configuration Code in Home.Module.TS as below:
const isIE = window.navigator.userAgent.indexOf('MSIE ') > -1 || window.navigator.userAgent.indexOf('Trident/') > -1;
export function loggerCallback(logLevel: LogLevel, message: string) {
console.log(message);
}
export function MSALInstanceFactory(): IPublicClientApplication {
return new PublicClientApplication({
auth: {
clientId: '551eb551-c9b8-423c-976e-fa795755b5df', //localhost env
authority:'https://login.microsoftonline.com/04ea39e3-ac5b-4971-937c-8344c97a4509/',
redirectUri:'http://localhost:4200/'
},
cache: {
cacheLocation: BrowserCacheLocation.SessionStorage,
storeAuthStateInCookie: isIE, // set to true for IE 11. Remove this line to use Angular Universal
},
system: {
loggerOptions: {
loggerCallback,
logLevel: LogLevel.Info,
piiLoggingEnabled: false
}
}
});
}
export function MSALInterceptorConfigFactory(): MsalInterceptorConfiguration {
const protectedResourceMap = new Map<string, Array<string>>();
protectedResourceMap.set('https://graph.microsoft.com/beta/me', ['user.read']); // Prod environment. Uncomment to use.
// protectedResourceMap.set('https://graph.microsoft-ppe.com/v1.0/me', ['user.read']);
return {
interactionType: InteractionType.Redirect,
protectedResourceMap
};
}
export function MSALGuardConfigFactory(): MsalGuardConfiguration {
return {
interactionType: InteractionType.Redirect,
authRequest: {
scopes: ['user.read']
},
// loginFailedRoute: '/login-failed'
};
}
And In Home-Routing.Module.TS, I have written below line to route to Landing Component.
const routes: Routes = [
{ path: '', component: LandingComponentComponent, canActivate:[MsalGuard] },
];
And I have activated the MSAL Guard in LandingComponentComponent where after authenticating from Microsoft, user gets logged in.
Below is my Landing.Component.TS file :
isIframe = false;
loginDisplay = false;
ngOnInit(): void {
this.isIframe = window !== window.parent && !window.opener; // Remove this line to use Angular Universal
this.setLoginDisplay();
this.getProfile();
this.msalBroadcastService.inProgress$
.pipe(
filter((status: InteractionStatus) => status === InteractionStatus.None),
takeUntil(this._destroying$)
)
.subscribe(() => {
this.setLoginDisplay();
this.checkAndSetActiveAccount();
})
localStorage.setItem("isLandingPage", "false");
this.httpService.post("getEmpList",{}).subscribe(
data => {
if (data.success) {
let data_ = data.data;
sessionStorage.setItem('UserList', JSON.stringify(data.data))
this._sharedService.setEmployeeData(data_);
} else {
if(data.msg === "Invalid Session")
{
alert("Session has been expired!! Please login again");
}
else
{
alert("Could not get employee details. Error: " + data.msg);
}
}
},
error => {
console.log(error);
alert("Could not get employee details. ");
}
)
}
setLoginDisplay() {
this.loginDisplay = this.authService.instance.getAllAccounts().length > 0;
}
checkAndSetActiveAccount() {
/**
* If no active account set but there are accounts signed in, sets first account to active account
* To use active account set here, subscribe to inProgress$ first in your component
* Note: Basic usage demonstrated. Your app may require more complicated account selection logic
*/
let activeAccount = this.authService.instance.getActiveAccount();
if (!activeAccount && this.authService.instance.getAllAccounts().length > 0) {
let accounts = this.authService.instance.getAllAccounts();
this.authService.instance.setActiveAccount(accounts[0]);
}
if (activeAccount) {
this.activeuser = activeAccount.username;
sessionStorage.setItem('username', this.activeuser)
}
}
getProfile() {
console.log("getprofile function");
this.http.get('https://graph.microsoft.com/beta/me').subscribe(res => {
this.res2 = JSON.stringify(res)
this.res3 = JSON.parse(this.res2)
sessionStorage.setItem("empid", this.res3.extension_6d1109881ca84719973dbff443d7b820_employeeNumber)
var empno = sessionStorage.getItem("empid")
console.log("empno", empno);
sessionStorage.setItem("emp_name", this.res3.displayName)
sessionStorage.setItem("emp_desg", this.res3.jobTitle)
sessionStorage.setItem("emp_emailid", this.res3.mail)
var empname = sessionStorage.getItem("emp_name")
var empdesg = sessionStorage.getItem("emp_desg")
var empmail = sessionStorage.getItem("emp_emailid")
console.log("empname emdesg empmail", empname, empdesg, empmail);
this.httpService.post("login", {
username: this.res3.extension_6d1109881ca84719973dbff443d7b820_employeeNumber
}).subscribe(
data => {
if (data.success) {
// if(data.data.emp_id){
console.log("data", data);
this._sharedService.setUserRole(data.data.menu[0].erole_id)
localStorage.setItem("emp_role", data.data.menu[0].erole_id);
this.role = Number(localStorage.getItem('emp_role'))
if(this.role === 8 || this.role === 10 || this.role === 11 ){
this.role_flag = true
}else{
this.role_flag = false
}
localStorage.setItem("isLoggedIn", "true");
localStorage.setItem("isLandingPage", "true");
localStorage.setItem("emp_id", this.res3.extension_6d1109881ca84719973dbff443d7b820_employeeNumber);
localStorage.setItem("emp_name", this.res3.displayName);
localStorage.setItem("emp_desg", this.res3.jobTitle);
localStorage.setItem("loginDetails", JSON.stringify(data.data));
// }
// this.router.navigate(['/home']);
} else {
if (data.msg === "Invalid Session") {
alert("Session has been expired!! Please login again");
}
else {
alert("No Role Detected !");
}
}
},
error => {
console.log(error);
alert("Error Occurred! Please try again...")
}
)
})
}
login() {
this.authService.loginPopup()
.subscribe({
next: (result) => {
// console.log(result);
this.setLoginDisplay();
},
error: (error) => console.log(error)
});
}
loginRedirect() {
if (this.msalGuardConfig.authRequest) {
this.authService.loginRedirect({ ...this.msalGuardConfig.authRequest } as RedirectRequest);
} else {
this.authService.loginRedirect();
}
}
loginPopup() {
if (this.msalGuardConfig.authRequest) {
this.authService.loginPopup({ ...this.msalGuardConfig.authRequest } as PopupRequest)
.subscribe((response: AuthenticationResult) => {
this.authService.instance.setActiveAccount(response.account);
// console.log('.......................>', response.account)
});
} else {
this.authService.loginPopup()
.subscribe((response: AuthenticationResult) => {
this.authService.instance.setActiveAccount(response.account);
});
}
}
logout(popup?: boolean) {
if (popup) {
this.authService.logoutPopup({
mainWindowRedirectUri: "/"
});
} else {
this.authService.logoutRedirect();
}
}
ngOnDestroy(): void {
this._destroying$.next(undefined);
this._destroying$.complete();
}
showWelcomeMessage() {
this.authService.instance.getActiveAccount + " to Microsoft Graph API";
}
}
I tried “ng serve” in my VSCODE terminal and in the browser, I got a blank screen with an error message in Console Tab as:
Error: Uncaught (in promise): TypeError: Class constructor MsalGuard cannot be invoked without 'new'
TypeError: Class constructor MsalGuard cannot be invoked without 'new'
at router.mjs:3339:52
at R3Injector.runInContext (core.mjs:9276:20)
at router.mjs:3339:33
at Observable._subscribe (defer.js:5:19)
at Observable._trySubscribe (Observable.js:37:25)
at Observable.js:31:30
at errorContext (errorContext.js:19:9)
at Observable.subscribe (Observable.js:22:21)
at take.js:10:20
at OperatorSubscriber.<anonymous> (lift.js:10:28)
at resolvePromise (zone.js:1193:31)
at resolvePromise (zone.js:1147:17)
at zone.js:1260:17
at _ZoneDelegate.invokeTask (zone.js:402:31)
at core.mjs:10757:55
at AsyncStackTaggingZoneSpec.onInvokeTask (core.mjs:10757:36)
at _ZoneDelegate.invokeTask (zone.js:401:60)
at Object.onInvokeTask (core.mjs:11070:33)
at _ZoneDelegate.invokeTask (zone.js:401:60)
at Zone.runTask (zone.js:173:47)
I am not getting why this error is coming ?? Please help
Saloni Singh is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.