mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2024-11-29 08:56:52 +00:00
Fix CORS issue using Mongo Shell from new origin (#1422)
* Fix CORS issue using Mongo Shell from new origin * Add unit tests for getMongoShellOrigin and getMongoShellUrl * Fix lint errors
This commit is contained in:
parent
9d2d0e4754
commit
874cec26fc
@ -1,6 +1,6 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import * as Constants from "../../../Common/Constants";
|
import * as Constants from "../../../Common/Constants";
|
||||||
import { configContext, Platform } from "../../../ConfigContext";
|
import { configContext } from "../../../ConfigContext";
|
||||||
import * as ViewModels from "../../../Contracts/ViewModels";
|
import * as ViewModels from "../../../Contracts/ViewModels";
|
||||||
import { Action, ActionModifiers } from "../../../Shared/Telemetry/TelemetryConstants";
|
import { Action, ActionModifiers } from "../../../Shared/Telemetry/TelemetryConstants";
|
||||||
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
||||||
@ -9,6 +9,8 @@ import { isInvalidParentFrameOrigin, isReadyMessage } from "../../../Utils/Messa
|
|||||||
import { logConsoleError, logConsoleInfo, logConsoleProgress } from "../../../Utils/NotificationConsoleUtils";
|
import { logConsoleError, logConsoleInfo, logConsoleProgress } from "../../../Utils/NotificationConsoleUtils";
|
||||||
import Explorer from "../../Explorer";
|
import Explorer from "../../Explorer";
|
||||||
import TabsBase from "../TabsBase";
|
import TabsBase from "../TabsBase";
|
||||||
|
import { getMongoShellOrigin } from "./getMongoShellOrigin";
|
||||||
|
import { getMongoShellUrl } from "./getMongoShellUrl";
|
||||||
|
|
||||||
//eslint-disable-next-line
|
//eslint-disable-next-line
|
||||||
class MessageType {
|
class MessageType {
|
||||||
@ -47,7 +49,6 @@ export default class MongoShellTabComponent extends Component<
|
|||||||
IMongoShellTabComponentProps,
|
IMongoShellTabComponentProps,
|
||||||
IMongoShellTabComponentStates
|
IMongoShellTabComponentStates
|
||||||
> {
|
> {
|
||||||
private _runtimeEndpoint: string;
|
|
||||||
private _logTraces: Map<string, number>;
|
private _logTraces: Map<string, number>;
|
||||||
|
|
||||||
constructor(props: IMongoShellTabComponentProps) {
|
constructor(props: IMongoShellTabComponentProps) {
|
||||||
@ -55,7 +56,7 @@ export default class MongoShellTabComponent extends Component<
|
|||||||
this._logTraces = new Map();
|
this._logTraces = new Map();
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
url: this.getURL(),
|
url: getMongoShellUrl(),
|
||||||
};
|
};
|
||||||
|
|
||||||
props.onMongoShellTabAccessor({
|
props.onMongoShellTabAccessor({
|
||||||
@ -65,38 +66,6 @@ export default class MongoShellTabComponent extends Component<
|
|||||||
window.addEventListener("message", this.handleMessage.bind(this), false);
|
window.addEventListener("message", this.handleMessage.bind(this), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getURL(): string {
|
|
||||||
const { databaseAccount: account } = userContext;
|
|
||||||
const resourceId = account?.id;
|
|
||||||
const accountName = account?.name;
|
|
||||||
const mongoEndpoint = account?.properties?.mongoEndpoint || account?.properties?.documentEndpoint;
|
|
||||||
|
|
||||||
this._runtimeEndpoint = configContext.platform === Platform.Hosted ? configContext.BACKEND_ENDPOINT : "";
|
|
||||||
const extensionEndpoint: string = configContext.BACKEND_ENDPOINT || this._runtimeEndpoint || "";
|
|
||||||
let baseUrl = "/content/mongoshell/dist/";
|
|
||||||
if (userContext.portalEnv === "localhost") {
|
|
||||||
baseUrl = "/content/mongoshell/";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (userContext.features.enableLegacyMongoShellV1 === true) {
|
|
||||||
return "/mongoshell/index.html";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (userContext.features.enableLegacyMongoShellV1Dist === true) {
|
|
||||||
return "/mongoshell/dist/index.html";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (userContext.features.enableLegacyMongoShellV2 === true) {
|
|
||||||
return "/mongoshell/indexv2.html";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (userContext.features.enableLegacyMongoShellV2Dist === true) {
|
|
||||||
return "/mongoshell/dist/indexv2.html";
|
|
||||||
}
|
|
||||||
|
|
||||||
return `${extensionEndpoint}${baseUrl}index.html?resourceId=${resourceId}&accountName=${accountName}&mongoEndpoint=${mongoEndpoint}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
//eslint-disable-next-line
|
//eslint-disable-next-line
|
||||||
public setContentFocus(event: React.SyntheticEvent<HTMLIFrameElement, Event>): void {}
|
public setContentFocus(event: React.SyntheticEvent<HTMLIFrameElement, Event>): void {}
|
||||||
|
|
||||||
@ -152,6 +121,7 @@ export default class MongoShellTabComponent extends Component<
|
|||||||
const collectionId = this.props.collection.id();
|
const collectionId = this.props.collection.id();
|
||||||
const apiEndpoint = configContext.BACKEND_ENDPOINT;
|
const apiEndpoint = configContext.BACKEND_ENDPOINT;
|
||||||
const encryptedAuthToken: string = userContext.accessToken;
|
const encryptedAuthToken: string = userContext.accessToken;
|
||||||
|
const targetOrigin = getMongoShellOrigin();
|
||||||
|
|
||||||
shellIframe.contentWindow.postMessage(
|
shellIframe.contentWindow.postMessage(
|
||||||
{
|
{
|
||||||
@ -167,7 +137,7 @@ export default class MongoShellTabComponent extends Component<
|
|||||||
apiEndpoint: apiEndpoint,
|
apiEndpoint: apiEndpoint,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
configContext.BACKEND_ENDPOINT
|
targetOrigin
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
73
src/Explorer/Tabs/MongoShellTab/getMongoShellOrigin.test.ts
Normal file
73
src/Explorer/Tabs/MongoShellTab/getMongoShellOrigin.test.ts
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import { extractFeatures } from "Platform/Hosted/extractFeatures";
|
||||||
|
import { configContext } from "../../../ConfigContext";
|
||||||
|
import { updateUserContext } from "../../../UserContext";
|
||||||
|
import { getMongoShellOrigin } from "./getMongoShellOrigin";
|
||||||
|
|
||||||
|
describe("getMongoShellOrigin", () => {
|
||||||
|
(window as { origin: string }).origin = "window_origin";
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
updateUserContext({
|
||||||
|
features: extractFeatures(
|
||||||
|
new URLSearchParams({
|
||||||
|
"feature.enableLegacyMongoShellV1": "false",
|
||||||
|
"feature.enableLegacyMongoShellV2": "false",
|
||||||
|
"feature.enableLegacyMongoShellV1Dist": "false",
|
||||||
|
"feature.enableLegacyMongoShellV2Dist": "false",
|
||||||
|
})
|
||||||
|
),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return BACKEND_ENDPOINT by default", () => {
|
||||||
|
expect(getMongoShellOrigin()).toBe(configContext.BACKEND_ENDPOINT);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return /mongoshell/index.html when enableLegacyMongoShellV1", () => {
|
||||||
|
updateUserContext({
|
||||||
|
features: extractFeatures(
|
||||||
|
new URLSearchParams({
|
||||||
|
"feature.enableLegacyMongoShellV1": "true",
|
||||||
|
})
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(getMongoShellOrigin()).toBe(window.origin);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return /mongoshell/index.html when enableLegacyMongoShellV2===true", () => {
|
||||||
|
updateUserContext({
|
||||||
|
features: extractFeatures(
|
||||||
|
new URLSearchParams({
|
||||||
|
"feature.enableLegacyMongoShellV2": "true",
|
||||||
|
})
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(getMongoShellOrigin()).toBe(window.origin);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return /mongoshell/index.html when enableLegacyMongoShellV1Dist===true", () => {
|
||||||
|
updateUserContext({
|
||||||
|
features: extractFeatures(
|
||||||
|
new URLSearchParams({
|
||||||
|
"feature.enableLegacyMongoShellV1Dist": "true",
|
||||||
|
})
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(getMongoShellOrigin()).toBe(window.origin);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return /mongoshell/index.html when enableLegacyMongoShellV2Dist===true", () => {
|
||||||
|
updateUserContext({
|
||||||
|
features: extractFeatures(
|
||||||
|
new URLSearchParams({
|
||||||
|
"feature.enableLegacyMongoShellV2Dist": "true",
|
||||||
|
})
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(getMongoShellOrigin()).toBe(window.origin);
|
||||||
|
});
|
||||||
|
});
|
15
src/Explorer/Tabs/MongoShellTab/getMongoShellOrigin.ts
Normal file
15
src/Explorer/Tabs/MongoShellTab/getMongoShellOrigin.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { configContext } from "../../../ConfigContext";
|
||||||
|
import { userContext } from "../../../UserContext";
|
||||||
|
|
||||||
|
export function getMongoShellOrigin(): string {
|
||||||
|
if (
|
||||||
|
userContext.features.enableLegacyMongoShellV1 === true ||
|
||||||
|
userContext.features.enableLegacyMongoShellV2 === true ||
|
||||||
|
userContext.features.enableLegacyMongoShellV1Dist === true ||
|
||||||
|
userContext.features.enableLegacyMongoShellV2Dist === true
|
||||||
|
) {
|
||||||
|
return window.origin;
|
||||||
|
}
|
||||||
|
|
||||||
|
return configContext.BACKEND_ENDPOINT;
|
||||||
|
}
|
179
src/Explorer/Tabs/MongoShellTab/getMongoShellUrl.test.ts
Normal file
179
src/Explorer/Tabs/MongoShellTab/getMongoShellUrl.test.ts
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
import { extractFeatures } from "Platform/Hosted/extractFeatures";
|
||||||
|
import { Platform, resetConfigContext, updateConfigContext } from "../../../ConfigContext";
|
||||||
|
import { updateUserContext, userContext } from "../../../UserContext";
|
||||||
|
import { getExtensionEndpoint, getMongoShellUrl } from "./getMongoShellUrl";
|
||||||
|
|
||||||
|
const mongoBackendEndpoint = "https://localhost:1234";
|
||||||
|
|
||||||
|
describe("getMongoShellUrl", () => {
|
||||||
|
let queryString = "";
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
resetConfigContext();
|
||||||
|
|
||||||
|
updateConfigContext({
|
||||||
|
BACKEND_ENDPOINT: mongoBackendEndpoint,
|
||||||
|
platform: Platform.Hosted,
|
||||||
|
});
|
||||||
|
|
||||||
|
updateUserContext({
|
||||||
|
subscriptionId: "fakeSubscriptionId",
|
||||||
|
resourceGroup: "fakeResourceGroup",
|
||||||
|
databaseAccount: {
|
||||||
|
id: "fakeId",
|
||||||
|
name: "fakeName",
|
||||||
|
location: "fakeLocation",
|
||||||
|
type: "fakeType",
|
||||||
|
kind: "fakeKind",
|
||||||
|
properties: {
|
||||||
|
documentEndpoint: "fakeDocumentEndpoint",
|
||||||
|
tableEndpoint: "fakeTableEndpoint",
|
||||||
|
gremlinEndpoint: "fakeGremlinEndpoint",
|
||||||
|
cassandraEndpoint: "fakeCassandraEndpoint",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
features: extractFeatures(
|
||||||
|
new URLSearchParams({
|
||||||
|
"feature.enableLegacyMongoShellV1": "false",
|
||||||
|
"feature.enableLegacyMongoShellV2": "false",
|
||||||
|
"feature.enableLegacyMongoShellV1Dist": "false",
|
||||||
|
"feature.enableLegacyMongoShellV2Dist": "false",
|
||||||
|
})
|
||||||
|
),
|
||||||
|
portalEnv: "prod",
|
||||||
|
});
|
||||||
|
|
||||||
|
queryString = `resourceId=${userContext.databaseAccount.id}&accountName=${userContext.databaseAccount.name}&mongoEndpoint=${userContext.databaseAccount.properties.documentEndpoint}`;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return {mongoBackendEndpoint}/content/mongoshell/dist/index.html by default ", () => {
|
||||||
|
expect(getMongoShellUrl()).toBe(`${mongoBackendEndpoint}/content/mongoshell/dist/index.html?${queryString}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return {mongoBackendEndpoint}/content/mongoshell/index.html when portalEnv==localhost ", () => {
|
||||||
|
updateUserContext({
|
||||||
|
portalEnv: "localhost",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(getMongoShellUrl()).toBe(`${mongoBackendEndpoint}/content/mongoshell/index.html?${queryString}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return {mongoBackendEndpoint}/content/mongoshell/dist/index.html when configContext.platform !== Platform.Hosted", () => {
|
||||||
|
updateConfigContext({
|
||||||
|
platform: Platform.Portal,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(getMongoShellUrl()).toBe(`${mongoBackendEndpoint}/content/mongoshell/dist/index.html?${queryString}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return /content/mongoshell/index.html when configContext.BACKEND_ENDPOINT === '' and configContext.platform === Platform.Hosted", () => {
|
||||||
|
resetConfigContext();
|
||||||
|
updateConfigContext({
|
||||||
|
platform: Platform.Hosted,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(getMongoShellUrl()).toBe(`/content/mongoshell/dist/index.html?${queryString}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return /content/mongoshell/index.html when configContext.BACKEND_ENDPOINT === '' and configContext.platform !== Platform.Hosted", () => {
|
||||||
|
resetConfigContext();
|
||||||
|
|
||||||
|
updateConfigContext({
|
||||||
|
platform: Platform.Portal,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(getMongoShellUrl()).toBe(`/content/mongoshell/dist/index.html?${queryString}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return /content/mongoshell/index.html when configContext.BACKEND_ENDPOINT !== '' and configContext.platform !== Platform.Hosted", () => {
|
||||||
|
resetConfigContext();
|
||||||
|
updateConfigContext({
|
||||||
|
platform: Platform.Portal,
|
||||||
|
BACKEND_ENDPOINT: mongoBackendEndpoint,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(getMongoShellUrl()).toBe(`${mongoBackendEndpoint}/content/mongoshell/dist/index.html?${queryString}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return /mongoshell/index.html when enableLegacyMongoShellV1===true", () => {
|
||||||
|
updateUserContext({
|
||||||
|
features: extractFeatures(
|
||||||
|
new URLSearchParams({
|
||||||
|
"feature.enableLegacyMongoShellV1": "true",
|
||||||
|
})
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(getMongoShellUrl()).toBe(`/mongoshell/index.html?${queryString}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return /mongoshell/index.html when enableLegacyMongoShellV2===true", () => {
|
||||||
|
updateUserContext({
|
||||||
|
features: extractFeatures(
|
||||||
|
new URLSearchParams({
|
||||||
|
"feature.enableLegacyMongoShellV2": "true",
|
||||||
|
})
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(getMongoShellUrl()).toBe(`/mongoshell/indexv2.html?${queryString}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return /mongoshell/index.html when enableLegacyMongoShellV1Dist===true", () => {
|
||||||
|
updateUserContext({
|
||||||
|
features: extractFeatures(
|
||||||
|
new URLSearchParams({
|
||||||
|
"feature.enableLegacyMongoShellV1Dist": "true",
|
||||||
|
})
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(getMongoShellUrl()).toBe(`/mongoshell/dist/index.html?${queryString}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return /mongoshell/index.html when enableLegacyMongoShellV2Dist===true", () => {
|
||||||
|
updateUserContext({
|
||||||
|
features: extractFeatures(
|
||||||
|
new URLSearchParams({
|
||||||
|
"feature.enableLegacyMongoShellV2Dist": "true",
|
||||||
|
})
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(getMongoShellUrl()).toBe(`/mongoshell/dist/indexv2.html?${queryString}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("getExtensionEndpoint", () => {
|
||||||
|
it("when platform === Platform.Hosted, backendEndpoint is undefined ", () => {
|
||||||
|
expect(getExtensionEndpoint(Platform.Hosted, undefined)).toBe("");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("when platform === Platform.Hosted, backendEndpoint === ''", () => {
|
||||||
|
expect(getExtensionEndpoint(Platform.Hosted, "")).toBe("");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("when platform === Platform.Hosted, backendEndpoint === null", () => {
|
||||||
|
expect(getExtensionEndpoint(Platform.Hosted, null)).toBe("");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("when platform === Platform.Hosted, backendEndpoint != '' ", () => {
|
||||||
|
expect(getExtensionEndpoint(Platform.Hosted, "foo")).toBe("foo");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("when platform === Platform.Portal, backendEndpoint is udefined ", () => {
|
||||||
|
expect(getExtensionEndpoint(Platform.Portal, undefined)).toBe("");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("when platform === Platform.Portal, backendEndpoint === '' ", () => {
|
||||||
|
expect(getExtensionEndpoint(Platform.Portal, "")).toBe("");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("when platform === Platform.Portal, backendEndpoint === null", () => {
|
||||||
|
expect(getExtensionEndpoint(Platform.Portal, null)).toBe("");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("when platform !== Platform.Portal, backendEndpoint != '' ", () => {
|
||||||
|
expect(getExtensionEndpoint(Platform.Portal, "foo")).toBe("foo");
|
||||||
|
});
|
||||||
|
});
|
42
src/Explorer/Tabs/MongoShellTab/getMongoShellUrl.ts
Normal file
42
src/Explorer/Tabs/MongoShellTab/getMongoShellUrl.ts
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import { configContext, Platform } from "../../../ConfigContext";
|
||||||
|
import { userContext } from "../../../UserContext";
|
||||||
|
|
||||||
|
export function getMongoShellUrl(): string {
|
||||||
|
const { databaseAccount: account } = userContext;
|
||||||
|
const resourceId = account?.id;
|
||||||
|
const accountName = account?.name;
|
||||||
|
const mongoEndpoint = account?.properties?.mongoEndpoint || account?.properties?.documentEndpoint;
|
||||||
|
const queryString = `resourceId=${resourceId}&accountName=${accountName}&mongoEndpoint=${mongoEndpoint}`;
|
||||||
|
|
||||||
|
if (userContext.features.enableLegacyMongoShellV1 === true) {
|
||||||
|
return `/mongoshell/index.html?${queryString}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userContext.features.enableLegacyMongoShellV1Dist === true) {
|
||||||
|
return `/mongoshell/dist/index.html?${queryString}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userContext.features.enableLegacyMongoShellV2 === true) {
|
||||||
|
return `/mongoshell/indexv2.html?${queryString}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userContext.features.enableLegacyMongoShellV2Dist === true) {
|
||||||
|
return `/mongoshell/dist/indexv2.html?${queryString}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const extensionEndpoint: string = getExtensionEndpoint(configContext.platform, configContext.BACKEND_ENDPOINT);
|
||||||
|
|
||||||
|
if (userContext.portalEnv === "localhost") {
|
||||||
|
return `${extensionEndpoint}/content/mongoshell/index.html?${queryString}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${extensionEndpoint}/content/mongoshell/dist/index.html?${queryString}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getExtensionEndpoint(platform: string, backendEndpoint: string): string {
|
||||||
|
const runtimeEndpoint = platform === Platform.Hosted ? backendEndpoint : "";
|
||||||
|
|
||||||
|
const extensionEndpoint: string = backendEndpoint || runtimeEndpoint || "";
|
||||||
|
|
||||||
|
return extensionEndpoint;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user