Upgrades to msal-browser (#781)
* Replaces msal with msal-browser * Remove unused id, logging in returns the tenant * format * Fix tenant switch * Removes v1 forceRefresh
This commit is contained in:
parent
4f3b2f7996
commit
a06e213b81
|
@ -275,6 +275,24 @@
|
||||||
"adal-node": "^0.1.28"
|
"adal-node": "^0.1.28"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@azure/msal-browser": {
|
||||||
|
"version": "2.14.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-2.14.2.tgz",
|
||||||
|
"integrity": "sha512-JKHE9Rer41CI8tweiyE91M8ZbGvQV9P+jOPB4ZtPxyxCi2f7ED3jNfdzyUJ1eGB+hCRnvO56M1Xc61T1R+JfYg==",
|
||||||
|
"requires": {
|
||||||
|
"@azure/msal-common": "^4.3.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@azure/msal-common": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-jFqUWe83wVb6O8cNGGBFg2QlKvqM1ezUgJTEV7kIsAPX0RXhGFE4B1DLNt6hCnkTXDbw+KGW0zgxOEr4MJQwLw==",
|
||||||
|
"requires": {
|
||||||
|
"debug": "^4.1.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"@azure/msal-common": {
|
"@azure/msal-common": {
|
||||||
"version": "1.7.2",
|
"version": "1.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-1.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-1.7.2.tgz",
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
"@azure/cosmos-language-service": "0.0.5",
|
"@azure/cosmos-language-service": "0.0.5",
|
||||||
"@azure/identity": "1.2.1",
|
"@azure/identity": "1.2.1",
|
||||||
"@azure/ms-rest-nodeauth": "3.0.7",
|
"@azure/ms-rest-nodeauth": "3.0.7",
|
||||||
|
"@azure/msal-browser": "2.14.2",
|
||||||
"@babel/plugin-proposal-class-properties": "7.12.1",
|
"@babel/plugin-proposal-class-properties": "7.12.1",
|
||||||
"@babel/plugin-proposal-decorators": "7.12.12",
|
"@babel/plugin-proposal-decorators": "7.12.12",
|
||||||
"@fluentui/react": "8.14.3",
|
"@fluentui/react": "8.14.3",
|
||||||
|
@ -75,7 +76,6 @@
|
||||||
"mkdirp": "1.0.4",
|
"mkdirp": "1.0.4",
|
||||||
"monaco-editor": "0.18.1",
|
"monaco-editor": "0.18.1",
|
||||||
"ms": "2.1.3",
|
"ms": "2.1.3",
|
||||||
"msal": "1.4.4",
|
|
||||||
"p-retry": "4.2.0",
|
"p-retry": "4.2.0",
|
||||||
"plotly.js-cartesian-dist-min": "1.52.3",
|
"plotly.js-cartesian-dist-min": "1.52.3",
|
||||||
"post-robot": "10.0.42",
|
"post-robot": "10.0.42",
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
jest.mock("../../../hooks/useDirectories");
|
jest.mock("../../../hooks/useDirectories");
|
||||||
|
import { AccountInfo } from "@azure/msal-browser";
|
||||||
import "@testing-library/jest-dom";
|
import "@testing-library/jest-dom";
|
||||||
import { fireEvent, render, screen } from "@testing-library/react";
|
import { fireEvent, render, screen } from "@testing-library/react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { MeControl } from "./MeControl";
|
import { MeControl } from "./MeControl";
|
||||||
import { Account } from "msal";
|
|
||||||
|
|
||||||
it("renders", () => {
|
it("renders", () => {
|
||||||
const account = {} as Account;
|
const account = {} as AccountInfo;
|
||||||
const logout = jest.fn();
|
const logout = jest.fn();
|
||||||
const openPanel = jest.fn();
|
const openPanel = jest.fn();
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import { FocusZone, DefaultButton, DirectionalHint, Persona, PersonaInitialsColor, PersonaSize } from "@fluentui/react";
|
import { AccountInfo } from "@azure/msal-browser";
|
||||||
|
import { DefaultButton, DirectionalHint, FocusZone, Persona, PersonaInitialsColor, PersonaSize } from "@fluentui/react";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { Account } from "msal";
|
|
||||||
import { useGraphPhoto } from "../../../hooks/useGraphPhoto";
|
import { useGraphPhoto } from "../../../hooks/useGraphPhoto";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
graphToken: string;
|
graphToken: string;
|
||||||
account: Account;
|
account: AccountInfo;
|
||||||
openPanel: () => void;
|
openPanel: () => void;
|
||||||
logout: () => void;
|
logout: () => void;
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ export const MeControl: React.FunctionComponent<Props> = ({ openPanel, logout, a
|
||||||
<Persona
|
<Persona
|
||||||
imageUrl={photo}
|
imageUrl={photo}
|
||||||
text={account?.name}
|
text={account?.name}
|
||||||
secondaryText={account?.userName}
|
secondaryText={account?.username}
|
||||||
showSecondaryText={true}
|
showSecondaryText={true}
|
||||||
showInitialsUntilImageLoads={true}
|
showInitialsUntilImageLoads={true}
|
||||||
initialsColor={PersonaInitialsColor.teal}
|
initialsColor={PersonaInitialsColor.teal}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import * as React from "react";
|
import * as msal from "@azure/msal-browser";
|
||||||
import { useBoolean } from "@fluentui/react-hooks";
|
import { useBoolean } from "@fluentui/react-hooks";
|
||||||
import { UserAgentApplication, Account, Configuration } from "msal";
|
import * as React from "react";
|
||||||
|
|
||||||
const config: Configuration = {
|
const config: msal.Configuration = {
|
||||||
cache: {
|
cache: {
|
||||||
cacheLocation: "localStorage",
|
cacheLocation: "localStorage",
|
||||||
},
|
},
|
||||||
|
@ -16,9 +16,9 @@ if (process.env.NODE_ENV === "development") {
|
||||||
config.auth.redirectUri = "https://dataexplorer-dev.azurewebsites.net";
|
config.auth.redirectUri = "https://dataexplorer-dev.azurewebsites.net";
|
||||||
}
|
}
|
||||||
|
|
||||||
const msal = new UserAgentApplication(config);
|
const msalInstance = new msal.PublicClientApplication(config);
|
||||||
|
|
||||||
const cachedAccount = msal.getAllAccounts()?.[0];
|
const cachedAccount = msalInstance.getAllAccounts()?.[0];
|
||||||
const cachedTenantId = localStorage.getItem("cachedTenantId");
|
const cachedTenantId = localStorage.getItem("cachedTenantId");
|
||||||
|
|
||||||
interface ReturnType {
|
interface ReturnType {
|
||||||
|
@ -28,7 +28,7 @@ interface ReturnType {
|
||||||
login: () => void;
|
login: () => void;
|
||||||
logout: () => void;
|
logout: () => void;
|
||||||
tenantId: string;
|
tenantId: string;
|
||||||
account: Account;
|
account: msal.AccountInfo;
|
||||||
switchTenant: (tenantId: string) => void;
|
switchTenant: (tenantId: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,13 +36,14 @@ export function useAADAuth(): ReturnType {
|
||||||
const [isLoggedIn, { setTrue: setLoggedIn, setFalse: setLoggedOut }] = useBoolean(
|
const [isLoggedIn, { setTrue: setLoggedIn, setFalse: setLoggedOut }] = useBoolean(
|
||||||
Boolean(cachedAccount && cachedTenantId) || false
|
Boolean(cachedAccount && cachedTenantId) || false
|
||||||
);
|
);
|
||||||
const [account, setAccount] = React.useState<Account>(cachedAccount);
|
const [account, setAccount] = React.useState<msal.AccountInfo>(cachedAccount);
|
||||||
const [tenantId, setTenantId] = React.useState<string>(cachedTenantId);
|
const [tenantId, setTenantId] = React.useState<string>(cachedTenantId);
|
||||||
const [graphToken, setGraphToken] = React.useState<string>();
|
const [graphToken, setGraphToken] = React.useState<string>();
|
||||||
const [armToken, setArmToken] = React.useState<string>();
|
const [armToken, setArmToken] = React.useState<string>();
|
||||||
|
|
||||||
|
msalInstance.setActiveAccount(account);
|
||||||
const login = React.useCallback(async () => {
|
const login = React.useCallback(async () => {
|
||||||
const response = await msal.loginPopup();
|
const response = await msalInstance.loginPopup();
|
||||||
setLoggedIn();
|
setLoggedIn();
|
||||||
setAccount(response.account);
|
setAccount(response.account);
|
||||||
setTenantId(response.tenantId);
|
setTenantId(response.tenantId);
|
||||||
|
@ -52,13 +53,14 @@ export function useAADAuth(): ReturnType {
|
||||||
const logout = React.useCallback(() => {
|
const logout = React.useCallback(() => {
|
||||||
setLoggedOut();
|
setLoggedOut();
|
||||||
localStorage.removeItem("cachedTenantId");
|
localStorage.removeItem("cachedTenantId");
|
||||||
msal.logout();
|
msalInstance.logoutRedirect();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const switchTenant = React.useCallback(
|
const switchTenant = React.useCallback(
|
||||||
async (id) => {
|
async (id) => {
|
||||||
const response = await msal.loginPopup({
|
const response = await msalInstance.loginPopup({
|
||||||
authority: `https://login.microsoftonline.com/${id}`,
|
authority: `https://login.microsoftonline.com/${id}`,
|
||||||
|
scopes: [],
|
||||||
});
|
});
|
||||||
setTenantId(response.tenantId);
|
setTenantId(response.tenantId);
|
||||||
setAccount(response.account);
|
setAccount(response.account);
|
||||||
|
@ -69,15 +71,11 @@ export function useAADAuth(): ReturnType {
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (account && tenantId) {
|
if (account && tenantId) {
|
||||||
Promise.all([
|
Promise.all([
|
||||||
msal.acquireTokenSilent({
|
msalInstance.acquireTokenSilent({
|
||||||
// There is a bug in MSALv1 that requires us to refresh the token. Their internal cache is not respecting authority
|
|
||||||
forceRefresh: true,
|
|
||||||
authority: `https://login.microsoftonline.com/${tenantId}`,
|
authority: `https://login.microsoftonline.com/${tenantId}`,
|
||||||
scopes: ["https://graph.windows.net//.default"],
|
scopes: ["https://graph.windows.net//.default"],
|
||||||
}),
|
}),
|
||||||
msal.acquireTokenSilent({
|
msalInstance.acquireTokenSilent({
|
||||||
// There is a bug in MSALv1 that requires us to refresh the token. Their internal cache is not respecting authority
|
|
||||||
forceRefresh: true,
|
|
||||||
authority: `https://login.microsoftonline.com/${tenantId}`,
|
authority: `https://login.microsoftonline.com/${tenantId}`,
|
||||||
scopes: ["https://management.azure.com//.default"],
|
scopes: ["https://management.azure.com//.default"],
|
||||||
}),
|
}),
|
||||||
|
|
Loading…
Reference in New Issue