From 7116f25ce42b983e69c6ec932b778b9c2ac696b3 Mon Sep 17 00:00:00 2001 From: Steve Faulkner <471400+southpolesteve@users.noreply.github.com> Date: Wed, 30 Dec 2020 13:18:03 -0600 Subject: [PATCH] checkpoint --- .../AccountSwitch/AccountSwitchComponent.tsx | 204 +++++++++--------- src/HostedExplorer.tsx | 185 +++++++--------- src/Platform/Hosted/ConnectScreen.tsx | 52 ----- src/contexts/authContext.tsx | 74 +++++++ src/hooks/useAADAccount.tsx | 8 - src/hooks/useAADToken.tsx | 20 -- src/hooks/useDatabaseAccounts.tsx | 52 +++++ src/hooks/useGraphPhoto.tsx | 14 +- src/hooks/useGraphProfile.tsx | 43 ---- src/hooks/useSubscriptions.tsx | 42 +--- 10 files changed, 316 insertions(+), 378 deletions(-) delete mode 100644 src/Platform/Hosted/ConnectScreen.tsx create mode 100644 src/contexts/authContext.tsx delete mode 100644 src/hooks/useAADAccount.tsx delete mode 100644 src/hooks/useAADToken.tsx create mode 100644 src/hooks/useDatabaseAccounts.tsx delete mode 100644 src/hooks/useGraphProfile.tsx diff --git a/src/Explorer/Controls/AccountSwitch/AccountSwitchComponent.tsx b/src/Explorer/Controls/AccountSwitch/AccountSwitchComponent.tsx index d00ca5fc4..5af0e352a 100644 --- a/src/Explorer/Controls/AccountSwitch/AccountSwitchComponent.tsx +++ b/src/Explorer/Controls/AccountSwitch/AccountSwitchComponent.tsx @@ -6,57 +6,120 @@ import { DefaultButton, IButtonStyles, IButtonProps } from "office-ui-fabric-rea import { IContextualMenuProps } from "office-ui-fabric-react/lib/ContextualMenu"; import { Dropdown, IDropdownOption, IDropdownProps } from "office-ui-fabric-react/lib/Dropdown"; import { useSubscriptions } from "../../../hooks/useSubscriptions"; +import { useDatabaseAccounts } from "../../../hooks/useDatabaseAccounts"; + +const buttonStyles: IButtonStyles = { + root: { + fontSize: StyleConstants.DefaultFontSize, + height: 40, + padding: 0, + paddingLeft: 10, + marginRight: 5, + backgroundColor: StyleConstants.BaseDark, + color: StyleConstants.BaseLight + }, + rootHovered: { + backgroundColor: StyleConstants.BaseHigh, + color: StyleConstants.BaseLight + }, + rootFocused: { + backgroundColor: StyleConstants.BaseHigh, + color: StyleConstants.BaseLight + }, + rootPressed: { + backgroundColor: StyleConstants.BaseHigh, + color: StyleConstants.BaseLight + }, + rootExpanded: { + backgroundColor: StyleConstants.BaseHigh, + color: StyleConstants.BaseLight + }, + textContainer: { + flexGrow: "initial" + } +}; export const AccountSwitchComponent: React.FunctionComponent = () => { const subscriptions = useSubscriptions(); + const [selectedSubscriptionId, setSelectedSubscriptionId] = React.useState(); + const accounts = useDatabaseAccounts(selectedSubscriptionId); + const [selectedAccountName, setSelectedAccoutName] = React.useState(); + const menuProps: IContextualMenuProps = { directionalHintFixed: true, className: "accountSwitchContextualMenu", items: [ { key: "switchSubscription", - onRender: () => renderSubscriptionDropdown(subscriptions) + onRender: () => { + // const placeHolderText = isLoadingSubscriptions + // ? "Loading subscriptions" + // : !options || !options.length + // ? "No subscriptions found in current directory" + // : "Select subscription from list"; + + const dropdownProps: IDropdownProps = { + label: "Subscription", + className: "accountSwitchSubscriptionDropdown", + options: subscriptions.map(sub => { + return { + key: sub.subscriptionId, + text: sub.displayName, + data: sub + }; + }), + onChange: (event, option) => { + setSelectedSubscriptionId(String(option.key)); + }, + defaultSelectedKey: selectedSubscriptionId, + placeholder: "Select subscription from list", + styles: { + callout: "accountSwitchSubscriptionDropdownMenu" + } + }; + + return ; + } }, { key: "switchAccount", - onRender: renderAccountDropDown + onRender: () => { + const isLoadingAccounts = false; + + const options = accounts.map(account => ({ + key: account.name, + text: account.name, + data: account + })); + + const placeHolderText = isLoadingAccounts + ? "Loading Cosmos DB accounts" + : !options || !options.length + ? "No Cosmos DB accounts found" + : "Select Cosmos DB account from list"; + + const dropdownProps: IDropdownProps = { + label: "Cosmos DB Account Name", + className: "accountSwitchAccountDropdown", + options, + onChange: (event, option) => { + setSelectedAccoutName(String(option.key)); + }, + defaultSelectedKey: selectedAccountName, + placeholder: placeHolderText, + styles: { + callout: "accountSwitchAccountDropdownMenu" + } + }; + + return ; + } } ] }; - const buttonStyles: IButtonStyles = { - root: { - fontSize: StyleConstants.DefaultFontSize, - height: 40, - padding: 0, - paddingLeft: 10, - marginRight: 5, - backgroundColor: StyleConstants.BaseDark, - color: StyleConstants.BaseLight - }, - rootHovered: { - backgroundColor: StyleConstants.BaseHigh, - color: StyleConstants.BaseLight - }, - rootFocused: { - backgroundColor: StyleConstants.BaseHigh, - color: StyleConstants.BaseLight - }, - rootPressed: { - backgroundColor: StyleConstants.BaseHigh, - color: StyleConstants.BaseLight - }, - rootExpanded: { - backgroundColor: StyleConstants.BaseHigh, - color: StyleConstants.BaseLight - }, - textContainer: { - flexGrow: "initial" - } - }; - const buttonProps: IButtonProps = { - text: "foo", + text: selectedAccountName || "Select Database Account", menuProps: menuProps, styles: buttonStyles, className: "accountSwitchButton", @@ -65,76 +128,3 @@ export const AccountSwitchComponent: React.FunctionComponent = () => { return ; }; - -function renderSubscriptionDropdown(subscriptions: Subscription[]): JSX.Element { - const selectedSubscriptionId = ""; - const isLoadingSubscriptions = false; - - const options: IDropdownOption[] = subscriptions.map(sub => { - return { - key: sub.subscriptionId, - text: sub.displayName, - data: sub - }; - }); - - const placeHolderText = isLoadingSubscriptions - ? "Loading subscriptions" - : !options || !options.length - ? "No subscriptions found in current directory" - : "Select subscription from list"; - - const dropdownProps: IDropdownProps = { - label: "Subscription", - className: "accountSwitchSubscriptionDropdown", - options: options, - onChange: () => {}, - defaultSelectedKey: selectedSubscriptionId, - placeholder: placeHolderText, - styles: { - callout: "accountSwitchSubscriptionDropdownMenu" - } - }; - - return ; -} - -function renderAccountDropDown(): JSX.Element { - const accounts = []; - const selectedAccountName = "foo"; - const isLoadingAccounts = false; - const options: IDropdownOption[] = accounts.map(account => { - return { - key: account.name, - text: account.name, - data: account - }; - }); - // Fabric UI will also try to select the first non-disabled option from dropdown. - // Add a option to prevent pop the message when user click on dropdown on first time. - options.unshift({ - key: "select from list", - text: "Select Cosmos DB account from list", - data: undefined - }); - - const placeHolderText = isLoadingAccounts - ? "Loading Cosmos DB accounts" - : !options || !options.length - ? "No Cosmos DB accounts found" - : "Select Cosmos DB account from list"; - - const dropdownProps: IDropdownProps = { - label: "Cosmos DB Account Name", - className: "accountSwitchAccountDropdown", - options: options, - onChange: () => {}, - defaultSelectedKey: selectedAccountName, - placeholder: placeHolderText, - styles: { - callout: "accountSwitchAccountDropdownMenu" - } - }; - - return ; -} diff --git a/src/HostedExplorer.tsx b/src/HostedExplorer.tsx index 33b946f3a..0ee8b82a1 100644 --- a/src/HostedExplorer.tsx +++ b/src/HostedExplorer.tsx @@ -1,5 +1,4 @@ -import { Configuration, PublicClientApplication } from "@azure/msal-browser"; -import { AuthenticatedTemplate, MsalProvider, UnauthenticatedTemplate, useMsal } from "@azure/msal-react"; +import "./Platform/Hosted/ConnectScreen.less"; import { useBoolean } from "@uifabric/react-hooks"; import { DefaultButton, @@ -17,65 +16,19 @@ import FeedbackIcon from "../images/Feedback.svg"; import ConnectIcon from "../images/HostedConnectwhite.svg"; import ChevronRight from "../images/chevron-right.svg"; import "../less/hostedexplorer.less"; -import { AccountSwitchComponent } from "./Explorer/Controls/AccountSwitch/AccountSwitchComponent"; import { CommandButtonComponent } from "./Explorer/Controls/CommandButton/CommandButtonComponent"; -import { DefaultDirectoryDropdownComponent } from "./Explorer/Controls/Directory/DefaultDirectoryDropdownComponent"; -import { DirectoryListComponent } from "./Explorer/Controls/Directory/DirectoryListComponent"; import "./Explorer/Menus/NavBar/MeControlComponent.less"; import { useGraphPhoto } from "./hooks/useGraphPhoto"; -import { ConnectScreen } from "./Platform/Hosted/ConnectScreen"; import "./Shared/appInsights"; -import { useAADAccount } from "./hooks/useAADAccount"; -import * as Msal from "msal"; -import { fetchMe } from "./hooks/useGraphProfile"; -import { fetchSubscriptions } from "./hooks/useSubscriptions"; +import { AccountSwitchComponent } from "./Explorer/Controls/AccountSwitch/AccountSwitchComponent"; +import { AuthContext, AuthProvider } from "./contexts/authContext"; initializeIcons(); -// MSAL configuration -const configuration: Configuration = { - auth: { - clientId: "203f1145-856a-4232-83d4-a43568fba23d", - redirectUri: "https://localhost:1234/hostedExplorer.html", - authority: "https://login.windows-ppe.net/common" - }, - cache: { - cacheLocation: "sessionStorage", - storeAuthStateInCookie: false - } -}; - -// const configuration: Configuration = { -// auth: { -// clientId: "b4d07291-7936-4c8e-b413-f58b6d1c67e8", -// redirectUri: "https://localhost:1234/hostedExplorer.html", -// authority: "https://login.microsoftonline.com/907765e9-1846-4d84-ad7f-a2f5030ef5ba" -// }, -// cache: { -// cacheLocation: "sessionStorage" -// } -// }; - -// const application = new PublicClientApplication(configuration); - -const msal = new Msal.UserAgentApplication({ - auth: { - authority: "https://login.microsoft.com/common", - clientId: "203f1145-856a-4232-83d4-a43568fba23d", - redirectUri: "https://dataexplorer-dev.azurewebsites.net" - } -}); - -// msal.handleRedirectCallback((error, response) => { -// console.log(error, response); -// debugger; -// // handle redirect response or error -// }); - const App: React.FunctionComponent = () => { const [isOpen, { setTrue: openPanel, setFalse: dismissPanel }] = useBoolean(false); - const { instance } = useMsal(); - const account = useAADAccount(); + const { isLoggedIn, login, account, logout } = React.useContext(AuthContext); + const [isConnectionStringVisible, { setTrue: showConnectionString }] = useBoolean(false); const photo = useGraphPhoto(); const menuProps = { @@ -105,7 +58,7 @@ const App: React.FunctionComponent = () => {
{ - instance.logout(); + logout(); }} > Sign out @@ -114,7 +67,6 @@ const App: React.FunctionComponent = () => { } ] }; - const personaProps = {}; // { // id: "commandbutton-settings", @@ -154,6 +106,7 @@ const App: React.FunctionComponent = () => { rootExpanded: { backgroundColor: "#393939" } } }; + return (
@@ -168,14 +121,16 @@ const App: React.FunctionComponent = () => { Microsoft Azure Cosmos DB - account separator - - {/* */} - REPLACE ME - Connection string mode; - + {isLoggedIn && account separator} + {isLoggedIn && ( + + + REPLACE ME - Connection string mode; + + )}
- + {isLoggedIn && ( { hasPopup={true} disabled={false} /> - - - - window.open( - "https://aka.ms/cosmosdbfeedback?subject=Cosmos%20DB%20Hosted%20Data%20Explorer%20Feedback" - ) - } - ariaLabel="feeback button" - tooltipText="Send feedback" - hasPopup={true} - disabled={false} - /> - + )} + + window.open("https://aka.ms/cosmosdbfeedback?subject=Cosmos%20DB%20Hosted%20Data%20Explorer%20Feedback") + } + ariaLabel="feeback button" + tooltipText="Send feedback" + hasPopup={true} + disabled={false} + />
- + {isLoggedIn ? ( { /> - - + ) : ( { - msal.loginPopup().then(foo => { - msal.acquireTokenSilent({ scopes: ["https://graph.windows.net//.default"] }).then(bar => { - debugger; - // const token = - // "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IjVPZjlQNUY5Z0NDd0NtRjJCT0hIeEREUS1EayIsImtpZCI6IjVPZjlQNUY5Z0NDd0NtRjJCT0hIeEREUS1EayJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuYXp1cmUuY29tLyIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzcyZjk4OGJmLTg2ZjEtNDFhZi05MWFiLTJkN2NkMDExZGI0Ny8iLCJpYXQiOjE2MDkyMDYwNDQsIm5iZiI6MTYwOTIwNjA0NCwiZXhwIjoxNjA5MjA5OTQ0LCJhY3IiOiIxIiwiYWlvIjoiQVpRQWEvOFNBQUFBYzZ3RmNHOWRDYTRDS2tXL2YxdnM5b3Z2Y0tqN3NLazJqc3c5MG1MRlJkclJLelZ3cnJpS0hMNXBua0tFejVlQWlXYTRwd2JHNXdKY240dkpLVUpXb2JGdmdkVXhteWd4NGlxOXk1Z0l6TW9zM25DRGdodCtxa3lyVGlrVzJ0WTA0amRLeFA2Q2wzWm10UzYxMmhmdkFkQVRBZ3Arc0w1TUdzU05KcElUR1dBZ1RKZXZ4c1dHek5Sb2hPOXdWVUN4IiwiYW1yIjpbInB3ZCIsInJzYSIsIm1mYSJdLCJhcHBpZCI6IjIwM2YxMTQ1LTg1NmEtNDIzMi04M2Q0LWE0MzU2OGZiYTIzZCIsImFwcGlkYWNyIjoiMCIsImRldmljZWlkIjoiMzI3NjNiYjktMDNlNS00ZDBkLTliZmEtZmEyY2U5OGQ1ZGVlIiwiZmFtaWx5X25hbWUiOiJGYXVsa25lciIsImdpdmVuX25hbWUiOiJTdGV2ZSIsImhhc2dyb3VwcyI6InRydWUiLCJpcGFkZHIiOiI0NS4yMi4xMjIuMjIwIiwibmFtZSI6IlN0ZXZlIEZhdWxrbmVyIiwib2lkIjoiN2M4Yjk4ZGItOTA3OC00NGM3LWE5YWItYzJiOGYxOGRiZDM2Iiwib25wcmVtX3NpZCI6IlMtMS01LTIxLTIxMjc1MjExODQtMTYwNDAxMjkyMC0xODg3OTI3NTI3LTMyMjM1ODIxIiwicHVpZCI6IjEwMDM3RkZFQUJDNTk0QjYiLCJyaCI6IjAuQVJvQXY0ajVjdkdHcjBHUnF5MTgwQkhiUjBVUlB5QnFoVEpDZzlTa05XajdvajBhQUprLiIsInNjcCI6InVzZXJfaW1wZXJzb25hdGlvbiIsInN1YiI6InNJV3JwSTFoQVNUWXJoUFVrYWp1NUtQb3Z6SHdzUkdnOTN3U2t1OEs0aW8iLCJ0aWQiOiI3MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDciLCJ1bmlxdWVfbmFtZSI6InN0ZmF1bEBtaWNyb3NvZnQuY29tIiwidXBuIjoic3RmYXVsQG1pY3Jvc29mdC5jb20iLCJ1dGkiOiJ2ME0xNVdjSWkwcVpwNTdEd1QwSUFnIiwidmVyIjoiMS4wIiwieG1zX3RjZHQiOjEyODkyNDE1NDd9.WD_NlNg2C9rOeES_zRDEIn9MQaNTElyd1NjmQ89dGg8PxCurhZpnuSNmv6J8KuAaiVtifppu64zP5nPDouAsdq5lWrJ5N6WZE9Aox0RuVMqoQRTYEYSeC0R-2wh_77G77zPHVq2qMTOHKz60_Que6_T5VTOFsNpfPzRQwqXmnIvUZnKqf6cBvxLyJYE2IsXSuOdB7jDNWfnsGv19Ew7IdScS4PoIrsVGX5E7rQ4B_bUoYm74ooiH8W0TmVXah21Z66fVAEzuWYlIX5G6ylmT9ncDefVon5JKKe5ksN5GrNjPpVVm3tyCwJeRO_zmtd7nqOZ6GLrn5hzR4CpKB63Fng"; - fetchMe(bar.accessToken).then(resp => { - debugger; - }); - }); - // msal.acquireTokenSilent({ scopes: ["https://graph.windows.net//.default"] }).then(bar => { - // debugger; - // }); - }); - }} + onClick={login} styles={{ rootHovered: { backgroundColor: "#393939", color: "#fff" }, rootFocused: { backgroundColor: "#393939", color: "#fff" }, rootPressed: { backgroundColor: "#393939", color: "#fff" } }} /> - + )}
- + {isLoggedIn ? (

LOGGED IN!

- {/* */} -
- - - -
@@ -279,4 +249,9 @@ const App: React.FunctionComponent = () => { ); }; -render(, document.body); +render( + + + , + document.body +); diff --git a/src/Platform/Hosted/ConnectScreen.tsx b/src/Platform/Hosted/ConnectScreen.tsx deleted file mode 100644 index f7e5bf7b5..000000000 --- a/src/Platform/Hosted/ConnectScreen.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import "./ConnectScreen.less"; -import * as React from "react"; -import { useMsal } from "@azure/msal-react"; -import { useBoolean } from "@uifabric/react-hooks"; - -export const ConnectScreen: React.FunctionComponent = () => { - const { instance } = useMsal(); - const [isConnectionStringVisible, { setTrue: showConnectionString }] = useBoolean(false); - - return ( -
-
-
-

- Azure Cosmos DB -

-

Welcome to Azure Cosmos DB

- {isConnectionStringVisible ? ( -
-

Connect to your account with connection string

-

- - - Error notification - - -

-

- -

-

instance.loginPopup()}> - Sign In with Azure Account -

-
- ) : ( -
- instance.loginPopup()} /> -

{ - showConnectionString(); - }} - > - Connect to your account with connection string -

-
- )} -
-
-
- ); -}; diff --git a/src/contexts/authContext.tsx b/src/contexts/authContext.tsx new file mode 100644 index 000000000..c792b9eef --- /dev/null +++ b/src/contexts/authContext.tsx @@ -0,0 +1,74 @@ +import * as React from "react"; +import * as Msal from "msal"; +import { createContext, useState, useCallback } from "react"; +import { useBoolean } from "@uifabric/react-hooks"; + +const defaultError = "Auth context method was called witout a AuthProvider component in the component tree"; + +const msal = new Msal.UserAgentApplication({ + auth: { + authority: "https://login.microsoft.com/common", + clientId: "203f1145-856a-4232-83d4-a43568fba23d", + redirectUri: "https://dataexplorer-dev.azurewebsites.net" + } +}); + +interface AuthContext { + isLoggedIn: boolean; + account?: Msal.Account; + graphToken?: string; + armToken?: string; + logout: () => unknown; + login: () => unknown; +} + +export const AuthContext = createContext({ + isLoggedIn: false, + login: () => { + throw Error(defaultError); + }, + logout: () => { + throw Error(defaultError); + } +}); + +export const AuthProvider: React.FunctionComponent = ({ children }) => { + const [isLoggedIn, { setTrue: setLoggedIn, setFalse: setLoggedOut }] = useBoolean(false); + const [account, setAccount] = useState(); + const [graphToken, setGraphToken] = useState(); + const [armToken, setArmToken] = useState(); + + const login = useCallback(() => { + msal.loginPopup().then(response => { + setLoggedIn(); + setAccount(response.account); + msal + .acquireTokenSilent({ scopes: ["https://graph.windows.net//.default"] }) + .then(resp => { + setGraphToken(resp.accessToken); + }) + .catch(e => { + console.error(e); + }); + msal + .acquireTokenSilent({ scopes: ["https://management.azure.com//.default"] }) + .then(resp => { + setArmToken(resp.accessToken); + }) + .catch(e => { + console.error(e); + }); + }); + }, []); + + const logout = useCallback(() => { + msal.logout(); + setLoggedOut(); + }, []); + + return ( + + {children} + + ); +}; diff --git a/src/hooks/useAADAccount.tsx b/src/hooks/useAADAccount.tsx deleted file mode 100644 index 19b223392..000000000 --- a/src/hooks/useAADAccount.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { AccountInfo } from "@azure/msal-browser"; -import { useAccount, useMsal } from "@azure/msal-react"; - -export function useAADAccount(): AccountInfo { - const { accounts } = useMsal(); - const account = useAccount(accounts[0] || {}); - return account; -} diff --git a/src/hooks/useAADToken.tsx b/src/hooks/useAADToken.tsx deleted file mode 100644 index 2582eb54b..000000000 --- a/src/hooks/useAADToken.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { useMsal } from "@azure/msal-react"; -import { useEffect, useState } from "react"; -import { useAADAccount } from "./useAADAccount"; - -export function useAADToken(): string { - const { instance } = useMsal(); - const account = useAADAccount(); - const [state, setState] = useState(); - - useEffect(() => { - console.log("Current account", account); - if (account) { - instance.acquireTokenSilent({ account, scopes: ["User.Read"] }).then(response => { - console.log("Fetched token", response.accessToken); - setState(response.accessToken); - }); - } - }, [account]); - return state; -} diff --git a/src/hooks/useDatabaseAccounts.tsx b/src/hooks/useDatabaseAccounts.tsx new file mode 100644 index 000000000..837f9331f --- /dev/null +++ b/src/hooks/useDatabaseAccounts.tsx @@ -0,0 +1,52 @@ +import { useContext, useEffect, useState } from "react"; +import { AuthContext } from "../contexts/authContext"; +import { DatabaseAccount } from "../Contracts/DataModels"; + +interface AccountListResult { + nextLink: string; + value: DatabaseAccount[]; +} + +export async function fetchDatabaseAccounts( + subscriptionIds: string[], + accessToken: string +): Promise { + const headers = new Headers(); + const bearer = `Bearer ${accessToken}`; + + headers.append("Authorization", bearer); + + if (!subscriptionIds || !subscriptionIds.length) { + return Promise.reject("No subscription passed in"); + } + + let accounts: Array = []; + + const subscriptionFilter = "subscriptionId eq '" + subscriptionIds.join("' or subscriptionId eq '") + "'"; + const urlFilter = `$filter=(${subscriptionFilter}) and (resourceType eq 'microsoft.documentdb/databaseaccounts')`; + let nextLink = `https://management.azure.com/resources?api-version=2020-01-01&${urlFilter}`; + + while (nextLink) { + const response: Response = await fetch(nextLink, { headers }); + const result: AccountListResult = + response.status === 204 || response.status === 304 ? undefined : await response.json(); + if (!response.ok) { + throw result; + } + nextLink = result.nextLink; + accounts = [...accounts, ...result.value]; + } + return accounts; +} + +export function useDatabaseAccounts(subscriptionId: string): DatabaseAccount[] { + const { armToken } = useContext(AuthContext); + const [state, setState] = useState(); + + useEffect(() => { + if (subscriptionId && armToken) { + fetchDatabaseAccounts([subscriptionId], armToken).then(response => setState(response)); + } + }, [subscriptionId, armToken]); + return state || []; +} diff --git a/src/hooks/useGraphPhoto.tsx b/src/hooks/useGraphPhoto.tsx index 3a9f75bff..efebc11de 100644 --- a/src/hooks/useGraphPhoto.tsx +++ b/src/hooks/useGraphPhoto.tsx @@ -1,5 +1,5 @@ -import { useEffect, useState } from "react"; -import { useAADToken } from "./useAADToken"; +import { useContext, useEffect, useState } from "react"; +import { AuthContext } from "../contexts/authContext"; export async function fetchPhoto(accessToken: string): Promise { const headers = new Headers(); @@ -13,19 +13,19 @@ export async function fetchPhoto(accessToken: string): Promise { headers: headers }; - return fetch("https://graph.microsoft.com/v1.0/me/photo/$value", options) + return fetch("https://graph.windows.net/me/thumbnailPhoto?api-version=1.6", options) .then(response => response.blob()) .catch(error => console.log(error)); } export function useGraphPhoto(): string { - const token = useAADToken(); const [photo, setPhoto] = useState(); + const { graphToken } = useContext(AuthContext); useEffect(() => { - if (token) { - fetchPhoto(token).then(response => setPhoto(URL.createObjectURL(response))); + if (graphToken) { + fetchPhoto(graphToken).then(response => setPhoto(URL.createObjectURL(response))); } - }, [token]); + }, [graphToken]); return photo; } diff --git a/src/hooks/useGraphProfile.tsx b/src/hooks/useGraphProfile.tsx deleted file mode 100644 index 36c2c503e..000000000 --- a/src/hooks/useGraphProfile.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { useEffect, useState } from "react"; -import { useAADToken } from "./useAADToken"; - -export async function fetchMe(accessToken: string): Promise { - const headers = new Headers(); - const bearer = `Bearer ${accessToken}`; - - headers.append("Authorization", bearer); - - const options = { - method: "GET", - headers: headers - }; - - return fetch("https://graph.windows.net/me?api-version=1.6", options) - .then(response => response.json()) - .catch(error => console.log(error)); -} - -interface ProfileResponse { - displayName: string; - givenName: string; - jobTitle: string; - mail: string; - mobilePhone: null; - officeLocation: string; - preferredLanguage: null; - surname: string; - userPrincipalName: string; - id: string; -} - -export function useGraphProfile(): ProfileResponse { - const token = useAADToken(); - const [profileResponse, setProfileResponse] = useState(); - - useEffect(() => { - if (token) { - fetchMe(token).then(response => setProfileResponse(response)); - } - }, [token]); - return profileResponse; -} diff --git a/src/hooks/useSubscriptions.tsx b/src/hooks/useSubscriptions.tsx index f9d89baf6..c6e8a5242 100644 --- a/src/hooks/useSubscriptions.tsx +++ b/src/hooks/useSubscriptions.tsx @@ -1,6 +1,6 @@ -import { useEffect, useState } from "react"; +import { useContext, useEffect, useState } from "react"; +import { AuthContext } from "../contexts/authContext"; import { Subscription } from "../Contracts/DataModels"; -import { useAADToken } from "./useAADToken"; interface SubscriptionListResult { nextLink: string; @@ -33,43 +33,13 @@ export async function fetchSubscriptions(accessToken: string): Promise(); useEffect(() => { - if (token) { - fetchSubscriptions(token).then(response => setState(response)); + if (armToken) { + fetchSubscriptions(armToken).then(response => setState(response)); } - }, [token]); + }, [armToken]); return state || []; } - -// const { accounts } = useMsal(); -// const account = useAccount(accounts[0] || {}); -// const { isLoading, isError, data, error } = useQuery( -// ["subscriptions", account.tenantId], -// async () => { -// let subscriptions: Array = []; - -// const fetchHeaders = await ArmResourceUtils._getAuthHeader(ArmResourceUtils._armAuthArea, tenantId); -// let nextLink = `${ArmResourceUtils._armEndpoint}/subscriptions?api-version=${ArmResourceUtils._armApiVersion}`; - -// while (nextLink) { -// const response: Response = await fetch(nextLink, { headers: fetchHeaders }); -// const result: SubscriptionListResult = -// response.status === 204 || response.status === 304 ? null : await response.json(); -// if (!response.ok) { -// throw result; -// } -// nextLink = result.nextLink; -// const validSubscriptions = result.value.filter( -// sub => sub.state === "Enabled" || sub.state === "Warned" || sub.state === "PastDue" -// ); -// subscriptions = [...subscriptions, ...validSubscriptions]; -// } -// return subscriptions; -// }, -// { enabled: account.tenantId } -// ); - -// console.log(isLoading, isError, data, error);