diff --git a/.eslintrc.js b/.eslintrc.js index 8695e29f2..1515c87cb 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -43,6 +43,7 @@ module.exports = { "@typescript-eslint/no-explicit-any": "error", "prefer-arrow/prefer-arrow-functions": ["error", { allowStandaloneDeclarations: true }], eqeqeq: "error", + "react/display-name": "off", "no-restricted-syntax": [ "error", { diff --git a/src/Main.tsx b/src/Main.tsx index e3ac0aa55..3ba187aea 100644 --- a/src/Main.tsx +++ b/src/Main.tsx @@ -55,7 +55,6 @@ import "url-polyfill/url-polyfill.min"; initializeIcons(); -import Hosted from "./Platform/Hosted/Main"; import { AuthType } from "./AuthType"; import { initializeIcons } from "office-ui-fabric-react/lib/Icons"; @@ -81,6 +80,8 @@ import { getDatabaseAccountPropertiesFromMetadata } from "./Platform/Hosted/HostedUtils"; import { DefaultExperienceUtility } from "./Shared/DefaultExperienceUtility"; +import { parseResourceTokenConnectionString } from "./Platform/Hosted/Helpers/ResourceTokenUtils"; +import { AccountKind, DefaultAccountExperience } from "./Common/Constants"; // const accountResourceId = // authType === AuthType.EncryptedToken @@ -138,10 +139,74 @@ const App: React.FunctionComponent = () => { }); explorer.isAccountReady(true); } else if (win.hostedConfig.authType === AuthType.ResourceToken) { - window.authType = AuthType.EncryptedToken; + window.authType = AuthType.ResourceToken; + // Resource tokens can only be used with SQL API + const apiExperience: string = DefaultAccountExperience.DocumentDB; + const parsedResourceToken = parseResourceTokenConnectionString(win.hostedConfig.resourceToken); + updateUserContext({ + resourceToken: parsedResourceToken.resourceToken + }); + return explorer.initDataExplorerWithFrameInputs({ + databaseAccount: { + id: "", + name: parsedResourceToken.accountEndpoint, + kind: AccountKind.GlobalDocumentDB, + properties: { documentEndpoint: parsedResourceToken.accountEndpoint }, + tags: { defaultExperience: apiExperience } + }, + subscriptionId: undefined, + resourceGroup: undefined, + masterKey: undefined, + hasWriteAccess: true, // TODO: we should embed this information in the token ideally + authorizationToken: undefined, + features: extractFeatures(), + csmEndpoint: undefined, + dnsSuffix: undefined, + serverId: AuthHeadersUtil.serverId, + extensionEndpoint: configContext.BACKEND_ENDPOINT, + subscriptionType: CollectionCreation.DefaultSubscriptionType, + quotaId: undefined, + addCollectionDefaultFlight: explorer.flight(), + isTryCosmosDBSubscription: explorer.isTryCosmosDBSubscription(), + isAuthWithresourceToken: true + }); } else if (win.hostedConfig.authType === AuthType.ConnectionString) { - // This might seem weird, but for legacy reasons lots of code expects a connection string login to look and act like an encrypted token login + // For legacy reasons lots of code expects a connection string login to look and act like an encrypted token login window.authType = AuthType.EncryptedToken; + // Impossible to tell if this is a try cosmos sub using an encrypted token + explorer.isTryCosmosDBSubscription(false); + updateUserContext({ + accessToken: encodeURIComponent(win.hostedConfig.encryptedToken) + }); + + const apiExperience: string = DefaultExperienceUtility.getDefaultExperienceFromApiKind( + win.hostedConfig.encryptedTokenMetadata.apiKind + ); + explorer.initDataExplorerWithFrameInputs({ + databaseAccount: { + id: "", + // id: Main._databaseAccountId, + name: win.hostedConfig.encryptedTokenMetadata.accountName, + kind: getDatabaseAccountKindFromExperience(apiExperience), + properties: getDatabaseAccountPropertiesFromMetadata(win.hostedConfig.encryptedTokenMetadata), + tags: [] + }, + subscriptionId: undefined, + resourceGroup: undefined, + masterKey: win.hostedConfig.masterKey, + hasWriteAccess: true, // TODO: we should embed this information in the token ideally + authorizationToken: undefined, + features: extractFeatures(), + csmEndpoint: undefined, + dnsSuffix: undefined, + serverId: AuthHeadersUtil.serverId, + extensionEndpoint: configContext.BACKEND_ENDPOINT, + subscriptionType: CollectionCreation.DefaultSubscriptionType, + quotaId: undefined, + addCollectionDefaultFlight: explorer.flight(), + isTryCosmosDBSubscription: explorer.isTryCosmosDBSubscription() + }); + explorer.isAccountReady(true); } else if (win.hostedConfig.authType === AuthType.AAD) { window.authType = AuthType.AAD; const account = win.hostedConfig.databaseAccount; diff --git a/src/Platform/Hosted/Components/AccountSwitcher.tsx b/src/Platform/Hosted/Components/AccountSwitcher.tsx index df77d3aaf..e4866b607 100644 --- a/src/Platform/Hosted/Components/AccountSwitcher.tsx +++ b/src/Platform/Hosted/Components/AccountSwitcher.tsx @@ -1,3 +1,6 @@ +// TODO: Renable this rule for the file or turn it off everywhere +/* eslint-disable react/display-name */ + import { StyleConstants } from "../../../Common/Constants"; import * as React from "react"; import { DefaultButton, IButtonStyles } from "office-ui-fabric-react/lib/Button"; @@ -69,12 +72,6 @@ export const AccountSwitcher: React.FunctionComponent = ({ armToken, setD { key: "switchSubscription", 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", @@ -103,12 +100,6 @@ export const AccountSwitcher: React.FunctionComponent = ({ armToken, setD { key: "switchAccount", onRender: (item, dismissMenu) => { - // 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", diff --git a/src/Platform/Hosted/Main.ts b/src/Platform/Hosted/Main.ts deleted file mode 100644 index 0ca930ff1..000000000 --- a/src/Platform/Hosted/Main.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { AuthType } from "../../AuthType"; -import * as Constants from "../../Common/Constants"; -import { configContext } from "../../ConfigContext"; -import { ApiKind, DatabaseAccount } from "../../Contracts/DataModels"; -import { DataExplorerInputsFrame } from "../../Contracts/ViewModels"; -import Explorer from "../../Explorer/Explorer"; -import "../../Explorer/Tables/DataTable/DataTableBindingManager"; -import { CollectionCreation, SubscriptionUtilMappings } from "../../Shared/Constants"; -import { DefaultExperienceUtility } from "../../Shared/DefaultExperienceUtility"; -import AuthHeadersUtil from "./Authorization"; -import { extractFeatures } from "./extractFeatures"; -import { getDatabaseAccountPropertiesFromMetadata } from "./HostedUtils"; - -export default class Main { - public static initDataExplorerFrameInputs( - explorer: Explorer, - masterKey?: string /* master key extracted from connection string if available */, - account?: DatabaseAccount, - authorizationToken?: string /* access key */ - ): void { - const serverId: string = AuthHeadersUtil.serverId; - const authType: string = (window).authType; - const accountResourceId = - authType === AuthType.EncryptedToken - ? Main._databaseAccountId - : authType === AuthType.AAD && account - ? account.id - : ""; - const subscriptionId: string = accountResourceId && accountResourceId.split("subscriptions/")[1].split("/")[0]; - const resourceGroup: string = accountResourceId && accountResourceId.split("resourceGroups/")[1].split("/")[0]; - - explorer.isTryCosmosDBSubscription(SubscriptionUtilMappings.FreeTierSubscriptionIds.indexOf(subscriptionId) >= 0); - if (authorizationToken && authorizationToken.indexOf("Bearer") !== 0) { - // Portal sends the auth token with bearer suffix, so we prepend the same to be consistent - authorizationToken = `Bearer ${authorizationToken}`; - } - - if (authType === AuthType.EncryptedToken) { - // TODO: Remove window.authType - window.authType = AuthType.EncryptedToken; - const apiExperience: string = DefaultExperienceUtility.getDefaultExperienceFromApiKind( - Main._accessInputMetadata.apiKind - ); - return explorer.initDataExplorerWithFrameInputs({ - databaseAccount: { - id: Main._databaseAccountId, - name: Main._accessInputMetadata.accountName, - kind: this._getDatabaseAccountKindFromExperience(apiExperience), - properties: getDatabaseAccountPropertiesFromMetadata(Main._accessInputMetadata), - tags: { defaultExperience: apiExperience } - }, - subscriptionId, - resourceGroup, - masterKey, - hasWriteAccess: true, // TODO: we should embed this information in the token ideally - authorizationToken: undefined, - features: extractFeatures(), - csmEndpoint: undefined, - dnsSuffix: null, - serverId: serverId, - extensionEndpoint: configContext.BACKEND_ENDPOINT, - subscriptionType: CollectionCreation.DefaultSubscriptionType, - quotaId: undefined, - addCollectionDefaultFlight: explorer.flight(), - isTryCosmosDBSubscription: explorer.isTryCosmosDBSubscription() - }); - } - - if (authType === AuthType.AAD) { - const inputs: DataExplorerInputsFrame = { - databaseAccount: account, - subscriptionId, - resourceGroup, - masterKey, - hasWriteAccess: true, //TODO: 425017 - support read access - authorizationToken, - features: extractFeatures(), - csmEndpoint: undefined, - dnsSuffix: null, - serverId: serverId, - extensionEndpoint: configContext.BACKEND_ENDPOINT, - subscriptionType: CollectionCreation.DefaultSubscriptionType, - quotaId: undefined, - addCollectionDefaultFlight: explorer.flight(), - isTryCosmosDBSubscription: explorer.isTryCosmosDBSubscription() - }; - return explorer.initDataExplorerWithFrameInputs(inputs); - } - - if (authType === AuthType.ResourceToken) { - const apiExperience: string = DefaultExperienceUtility.getDefaultExperienceFromApiKind( - Main._accessInputMetadata.apiKind - ); - return explorer.initDataExplorerWithFrameInputs({ - databaseAccount: { - id: Main._databaseAccountId, - name: Main._accessInputMetadata.accountName, - kind: this._getDatabaseAccountKindFromExperience(apiExperience), - properties: getDatabaseAccountPropertiesFromMetadata(Main._accessInputMetadata), - tags: { defaultExperience: apiExperience } - }, - subscriptionId, - resourceGroup, - masterKey, - hasWriteAccess: true, // TODO: we should embed this information in the token ideally - authorizationToken: undefined, - features: extractFeatures(), - csmEndpoint: undefined, - dnsSuffix: null, - serverId: serverId, - extensionEndpoint: configContext.BACKEND_ENDPOINT, - subscriptionType: CollectionCreation.DefaultSubscriptionType, - quotaId: undefined, - addCollectionDefaultFlight: explorer.flight(), - isTryCosmosDBSubscription: explorer.isTryCosmosDBSubscription(), - isAuthWithresourceToken: true - }); - } - - throw new Error(`Unsupported AuthType ${authType}`); - } -}