import { useBoolean } from "@fluentui/react-hooks"; import { initializeIcons } from "@fluentui/react"; import * as React from "react"; import { render } from "react-dom"; import ChevronRight from "../images/chevron-right.svg"; import "../less/hostedexplorer.less"; import { AuthType } from "./AuthType"; import { DatabaseAccount } from "./Contracts/DataModels"; import "./Explorer/Menus/NavBar/MeControlComponent.less"; import { useAADAuth } from "./hooks/useAADAuth"; import { useTokenMetadata } from "./hooks/usePortalAccessToken"; import { HostedExplorerChildFrame } from "./HostedExplorerChildFrame"; import { AccountSwitcher } from "./Platform/Hosted/Components/AccountSwitcher"; import { ConnectExplorer } from "./Platform/Hosted/Components/ConnectExplorer"; import { DirectoryPickerPanel } from "./Platform/Hosted/Components/DirectoryPickerPanel"; import { FeedbackCommandButton } from "./Platform/Hosted/Components/FeedbackCommandButton"; import { MeControl } from "./Platform/Hosted/Components/MeControl"; import { SignInButton } from "./Platform/Hosted/Components/SignInButton"; import "./Platform/Hosted/ConnectScreen.less"; import { extractMasterKeyfromConnectionString } from "./Platform/Hosted/HostedUtils"; import "./Shared/appInsights"; initializeIcons(); const App: React.FunctionComponent = () => { // For handling encrypted portal tokens sent via query paramter const params = new URLSearchParams(window.location.search); const [encryptedToken, setEncryptedToken] = React.useState(params && params.get("key")); const encryptedTokenMetadata = useTokenMetadata(encryptedToken); // For showing/hiding panel const [isOpen, { setTrue: openPanel, setFalse: dismissPanel }] = useBoolean(false); const { isLoggedIn, armToken, graphToken, aadToken, account, tenantId, logout, login, switchTenant } = useAADAuth(); const [databaseAccount, setDatabaseAccount] = React.useState(); const [authType, setAuthType] = React.useState(encryptedToken ? AuthType.EncryptedToken : undefined); const [connectionString, setConnectionString] = React.useState(); const ref = React.useRef(); React.useEffect(() => { // If ref.current is undefined no iframe has been rendered if (ref.current) { // In hosted mode, we can set global properties directly on the child iframe. // This is not possible in the portal where the iframes have different origins const frameWindow = ref.current.contentWindow as HostedExplorerChildFrame; // AAD authenticated uses ALWAYS using AAD authType if (isLoggedIn) { frameWindow.hostedConfig = { authType: AuthType.AAD, databaseAccount, authorizationToken: armToken, aadToken, }; } else if (authType === AuthType.EncryptedToken) { frameWindow.hostedConfig = { authType: AuthType.EncryptedToken, encryptedToken, encryptedTokenMetadata, }; } else if (authType === AuthType.ConnectionString) { frameWindow.hostedConfig = { authType: AuthType.ConnectionString, encryptedToken, encryptedTokenMetadata, masterKey: extractMasterKeyfromConnectionString(connectionString), }; } else if (authType === AuthType.ResourceToken) { frameWindow.hostedConfig = { authType: AuthType.ResourceToken, resourceToken: connectionString, }; } } }); const showExplorer = (isLoggedIn && databaseAccount) || (encryptedTokenMetadata && encryptedTokenMetadata) || (authType === AuthType.ResourceToken && connectionString); return ( <>
window.open("https://portal.azure.com", "_blank")} tabIndex={0} title="Go to Azure Portal" > Microsoft Azure Cosmos DB {(isLoggedIn || encryptedTokenMetadata?.accountName) && ( account separator )} {isLoggedIn && ( )} {!isLoggedIn && encryptedTokenMetadata?.accountName && ( {encryptedTokenMetadata?.accountName} )}
{isLoggedIn ? ( ) : ( )}
{showExplorer && ( // Ideally we would import and render data explorer like any other React component, however // because it still has a significant amount of Knockout code, this would lead to memory leaks. // Knockout does not have a way to tear down all of its binding and listeners with a single method. // It's possible this can be changed once all knockout code has been removed. )} {!isLoggedIn && !encryptedTokenMetadata && ( )} {isLoggedIn && } ); }; render(, document.getElementById("App"));