syncweek-react-aad / react-aad

A React wrapper for Azure AD using the Microsoft Authentication Library (MSAL). The easiest way to integrate AzureAD with your React for authentication.
MIT License
344 stars 94 forks source link

Getting Unhandled Rejection (TypeError): this.getAccount is not a function when I call await authProvider.getAccessToken() #189

Closed BladedGhost closed 4 years ago

BladedGhost commented 4 years ago

I am converting from react-azure-adb2c to react-aad-msal, I have all the code set as per the example but I seem to be getting a "Unhandled Rejection (TypeError): this.getAccount" once I call the getAccessToken or the getIdToken function, `Unhandled Rejection (TypeError): this.getAccount is not a function ▶ 15 stack frames were collapsed. Module../src/authConfig.js C:/Projects/Productizer/Productizer.Web/src/authConfig.js:41 38 | tokenRefreshUri: window.location.origin + "/auth.html" 39 | }; 40 |

41 | export const authProvider = new MsalAuthProvider( 42 | config, 43 | authenticationParameters, 44 | options View compiled __webpack_require__ C:/Projects/Productizer/Productizer.Web/webpack/bootstrap:785 782 | }; 783 | 784 | // Execute the module function 785 | modules[moduleId].call(module.exports, module, module.exports, hotCreateRequire(moduleId)); | ^ 786 | 787 | // Flag the module as loaded 788 | module.l = true; ....`

the stack also includes this error Uncaught (in promise) TypeError: Right-hand side of 'instanceof' is not an object, this gets thrown in the MsalAuthProvider.js file, at line 335 -> if (!(error instanceof InteractionRequiredAuthError)) {

if I hover over the error it has the following error -> Error: API does not accept non-array scopes at MsalAuthProvider.UserAgentApplication.validateInputScope (UserAgentApplication.js:620) at UserAgentApplication.js:1132 at new Promise () at MsalAuthProvider.UserAgentApplication.acquireTokenSilent (UserAgentApplication.js:1131) at MsalAuthProvider.descriptor.value [as acquireTokenSilent] (UserAgentApplication.js:75) at MsalAuthProvider._callee2$ (MsalAuthProvider.js:160) at tryCatch (runtime.js:45) at Generator.invoke [as _invoke] (runtime.js:264) at Generator.prototype. [as next] (runtime.js:98) at MsalAuthProvider.js:33 at new Promise () at push../node_modules/react-aad-msal/dist/esm/MsalAuthProvider.js.awaiter (MsalAuthProvider.js:10) at MsalAuthProvider._this.getAccessToken (MsalAuthProvider.js:146) at getToken$ (authConfig.js:82) at tryCatch (runtime.js:45) at Generator.invoke [as _invoke] (runtime.js:264) at Generator.prototype. [as next] (runtime.js:98) at tryCatch (runtime.js:45) at invoke (runtime.js:137) at runtime.js:172 at new Promise () at callInvokeWithMethodAndArg (runtime.js:171) at AsyncIterator.enqueue [as _invoke] (runtime.js:190) at AsyncIterator.prototype. [as next] (runtime.js:98) at Object.exports.async (runtime.js:211) at getToken (authConfig.js:82) at currentUser$ (authConfig.js:69) at tryCatch (runtime.js:45) at Generator.invoke [as _invoke] (runtime.js:264) at Generator.prototype. [as next] (runtime.js:98) at tryCatch (runtime.js:45) at invoke (runtime.js:137) at runtime.js:172 at new Promise () at callInvokeWithMethodAndArg (runtime.js:171) at AsyncIterator.enqueue [as _invoke] (runtime.js:190) at AsyncIterator.prototype. [as next] (runtime.js:98) at Object.exports.async (runtime.js:211) at currentUser (authConfig.js:69) at Module../src/services/AuthService.jsx (AuthService.jsx:5) at __webpack_require (bootstrap:785) at fn (bootstrap:150) at Module../src/services/index.ts (index.ts:1) at webpack_require (bootstrap:785) at fn (bootstrap:150) at Module../src/components/Navbars/AdminNavbarLinks.jsx (GridItem.jsx:21) at webpack_require (bootstrap:785) at fn (bootstrap:150) at Module../src/components/Navbars/Navbar.jsx (AdminNavbarLinks.scss?aaf8:37) at __webpack_require__ (bootstrap:785)

but I am providing an arrayed scope

this is my index.js file, I know it is sloppy code, but I just want to get this working first.

`import React from "react"; import ReactDOM from "react-dom"; import { createBrowserHistory } from "history"; import { Router, Route, Switch, Redirect } from "react-router-dom";

// core components import Admin from "layouts/Admin.jsx"; import RTL from "layouts/RTL.jsx";

import "primereact/resources/themes/rhea/theme.css"; import "primereact/resources/primereact.min.css"; import "primeicons/primeicons.css";

import "assets/css/material-dashboard-react.css?v=1.6.0"; import { getRoles } from "./services/AuthService"; import { AzureAD, AuthenticationState } from "react-aad-msal"; import { authProvider } from "./authConfig";

const hist = createBrowserHistory(); ReactDOM.render(

loading loading

, document.getElementById("root") ); getRoles().then(() => { ReactDOM.render(

{({ login, logout, authenticationState, error, accountInfo }) => { switch (authenticationState) { case AuthenticationState.Authenticated: return ( ); case AuthenticationState.InProgress: return

Authenticating

; case AuthenticationState.Unauthenticated: return
You are not authenticated.
; default: return
You are not authenticated.
; } }}
, document.getElementById("root") ); });` and this is my authConfig.jsx code which does all the auth stuff ` import decodeJWT from "jwt-decode"; import { Resources } from "./Resources/Resources"; import { LoginType, MsalAuthProvider } from "react-aad-msal"; const config = { auth: { clientID: "my application-id", authority: "https://login.microsoftonline.com/tfp", type: LoginType.Redirect, redirectUri: Resources.loginRedirect }, cache: { cacheLocation: "localStorage", storeAuthStateInCookie: true } }; const authenticationParameters = { scopes: ["https://[my company name].onmicrosoft.com/api/user_impersonation"] }; const options = { loginType: LoginType.Popup, tokenRefreshUri: window.location.origin + "/auth.html" }; export const authProvider = new MsalAuthProvider( config, authenticationParameters, options ); export const isLoggedIn = async () => { const token = await getToken(); if (token) { return true; } return false; }; export const logout = () => { authProvider.signOut(); }; export const currentUser = async () => { const decoded = decodeJWT((await getToken()).accessToken); return { name: decoded.name, firstName: decoded.given_name, lastName: decoded.family_name, emails: decoded.emails, city: decoded.city, country: decoded.country }; }; export const getToken = async () => await authProvider.getAccessToken(); export const getUser = async () => { const decoded = decodeJWT((await getToken()).accessToken); return decoded.emails[0]; }; .... ` **Reproduce** I have absolutely no idea how to reproduce this, it happens as the app starts up **Expected behavior** The app to login on startup **Desktop (please complete the following information):** - OS: Windows 10 latest update - Browser Chrome, Edge, Brave etc - Version All latest versions **Additional context** The get roles code does an api call which accesses this authProvider to get the token before anything else happens, I have tried to remove that code all-together to make sure that is not the issue, but then this same error comes up as soon as the AzureAD tag calls the authProvider. basically the same place the getRoles function gets this exception. **Some Notes** I did search on google with no help. I have been stuck on this issue for days now.
AndrewCraswell commented 4 years ago

Can you verify which version of react-aad-msal and msal you are using? I know you mentioned latest, but we ask because we frequently see people who haven't installed one of the peerDependencies at all.

BladedGhost commented 4 years ago

Can you verify which version of react-aad-msal and msal you are using? I know you mentioned latest, but we ask because we frequently see people who haven't installed one of the peerDependencies at all.

Seems like that was the issue, msal package was not installed, weird, I didn't see that this was a peer dependency...