import { FluentProvider, Link, MessageBar, MessageBarBody, webLightTheme } from "@fluentui/react-components"; import { useBoolean } from "@fluentui/react-hooks"; import { getErrorMessage } from "Common/ErrorHandlingUtils"; import { userContext } from "UserContext"; import * as React from "react"; import ConnectImage from "../../../../images/HdeConnectCosmosDB.svg"; import { AuthType } from "../../../AuthType"; import { HttpStatusCodes } from "../../../Common/Constants"; import { fetchEncryptedToken, isAccountRestrictedForConnectionStringLogin } from "../../../Common/PortalBackendClient"; import { AccessInputMetadata } from "../../../Contracts/DataModels"; import { parseConnectionString } from "../Helpers/ConnectionStringParser"; import { isResourceTokenConnectionString } from "../Helpers/ResourceTokenUtils"; import { isDirectConnectionStringLoginApi } from "../HostedUtils"; interface Props { connectionString: string; login: () => void; setEncryptedToken: (token: string) => void; setConnectionString: (connectionString: string) => void; setAuthType: (authType: AuthType) => void; setAccountMetadata: (metadata: AccessInputMetadata) => void; } export const ConnectExplorer: React.FunctionComponent = ({ setEncryptedToken, login, setAuthType, connectionString, setConnectionString, setAccountMetadata, }: Props) => { const [isFormVisible, { setTrue: showForm }] = useBoolean(false); const [errorMessage, setErrorMessage] = React.useState(""); const [isBlockedByFirewall, setIsBlockedByFirewall] = React.useState(false); const [isConnecting, setIsConnecting] = React.useState(false); const enableConnectionStringLogin = !userContext.features.disableConnectionStringLogin; return (

Azure Cosmos DB

Welcome to Azure Cosmos DB

{isFormVisible && enableConnectionStringLogin ? (
{ event.preventDefault(); if (isConnecting) { return; } setErrorMessage(""); setIsBlockedByFirewall(false); setIsConnecting(true); try { if (await isAccountRestrictedForConnectionStringLogin(connectionString)) { setErrorMessage( "This account has been blocked from connection-string login. Please go to cosmos.azure.com/aad for AAD based login.", ); setIsConnecting(false); return; } } catch (error) { setErrorMessage(getErrorMessage(error as Error)); setIsConnecting(false); return; } try { if (isResourceTokenConnectionString(connectionString)) { setAuthType(AuthType.ResourceToken); return; } const metadata = parseConnectionString(connectionString); if (!metadata) { setErrorMessage( "We couldn't recognize this connection string. Verify that it is a valid Azure Cosmos DB connection string and try again.", ); return; } if (isDirectConnectionStringLoginApi(metadata.apiKind)) { setAccountMetadata(metadata); setAuthType(AuthType.ConnectionString); return; } // Mongo and Cassandra go through the Portal Backend const encryptedToken = await fetchEncryptedToken(connectionString); setEncryptedToken(encryptedToken); setAuthType(AuthType.ConnectionString); } catch (error) { const errorDetails = await (error as Response).text(); setErrorMessage( errorDetails ? `Couldn't authenticate with Cosmos DB: ${errorDetails}` : "Failed to connect to the account. Please check the connection string and try again.", ); // A Forbidden usually means the account firewall dropped the request. The connection // string is exchanged by the Portal Backend rather than the browser, so the account has // to allowlist those services. setIsBlockedByFirewall((error as Response).status === HttpStatusCodes.Forbidden); } finally { setIsConnecting(false); } }} >

Connect to your account with connection string

{ setConnectionString(event.target.value); }} />

{errorMessage.length > 0 && ( {errorMessage} {isBlockedByFirewall && ( Allow access from Azure Portal )} )}

Sign In with Azure Account

) : (
{enableConnectionStringLogin && (

Connect to your account with connection string

)}
)}
); };