Compare commits

..

4 Commits

Author SHA1 Message Date
Tanuj Mittal
f788967ef2 Disable endtoendpuppeteer tests 2020-09-25 14:27:05 -07:00
Tanuj Mittal
823cbc4229 Do not fail when trying to find DE window with cross origin 2020-09-25 13:49:46 -07:00
Steve Faulkner
a04afc48e3 Fix hotfix syntax in workflow 2020-09-21 16:06:40 -05:00
artrejo
b86551c784 Remove AFEC check for Synapse Link and Mongo 2020-09-21 13:58:27 -07:00
12 changed files with 38 additions and 100 deletions

View File

@@ -3,8 +3,8 @@ on:
push:
branches:
- master
- hotfix/*
- release/*
- hotfix/**
- release/**
pull_request:
branches:
- master
@@ -196,26 +196,6 @@ jobs:
shell: bash
env:
NODE_TLS_REJECT_UNAUTHORIZED: 0
endtoendpuppeteer:
name: "End to end puppeteer tests"
needs: [lint, format, compile, unittest]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Use Node.js 12.x
uses: actions/setup-node@v1
with:
node-version: 12.x
- name: End to End Puppeteer Tests
run: |
npm ci
npm start &
npm run wait-for-server
npm run test:e2e
shell: bash
env:
NODE_TLS_REJECT_UNAUTHORIZED: 0
PORTAL_RUNNER_CONNECTION_STRING: ${{ secrets.CONNECTION_STRING_SQL }}
nuget:
name: Publish Nuget
if: github.ref == 'refs/heads/master' || contains(github.ref, 'hotfix/') || contains(github.ref, 'release/')

View File

@@ -48,16 +48,15 @@ export function sendCachedDataMessage<TResponseDataModel>(
export function sendMessage(data: any): void {
if (canSendMessage()) {
const dataExplorerWindow = getDataExplorerWindow(window);
if (dataExplorerWindow) {
dataExplorerWindow.parent.postMessage(
{
signature: "pcIframe",
data: data
},
dataExplorerWindow.document.referrer
);
}
// We try to find data explorer window first, then fallback to current window
const portalChildWindow = getDataExplorerWindow(window) || window;
portalChildWindow.parent.postMessage(
{
signature: "pcIframe",
data: data
},
portalChildWindow.document.referrer
);
}
}
@@ -66,15 +65,21 @@ export const getDataExplorerWindow = (currentWindow: Window): Window | undefined
// Start with the current window and traverse up the parent hierarchy to find a window
// with `dataExplorerPlatform` property
let dataExplorerWindow: Window | undefined = currentWindow;
// TODO: Need to `any` here since the window imports Explorer which can't be in strict mode yet
// eslint-disable-next-line @typescript-eslint/no-explicit-any
while (dataExplorerWindow && (dataExplorerWindow as any).dataExplorerPlatform == undefined) {
// If a window does not have a parent, its parent property is a reference to itself.
if (dataExplorerWindow.parent == dataExplorerWindow) {
dataExplorerWindow = undefined;
} else {
dataExplorerWindow = dataExplorerWindow.parent;
try {
// TODO: Need to `any` here since the window imports Explorer which can't be in strict mode yet
// eslint-disable-next-line @typescript-eslint/no-explicit-any
while (dataExplorerWindow && (dataExplorerWindow as any).dataExplorerPlatform == undefined) {
// If a window does not have a parent, its parent property is a reference to itself.
if (dataExplorerWindow.parent == dataExplorerWindow) {
dataExplorerWindow = undefined;
} else {
dataExplorerWindow = dataExplorerWindow.parent;
}
}
} catch (error) {
// This can happen if we come across parent from a different origin
dataExplorerWindow = undefined;
}
return dataExplorerWindow;

View File

@@ -6,7 +6,7 @@ export enum Platform {
interface ConfigContext {
platform: Platform;
allowedParentFrameOrigins: string[];
allowedParentFrameOrigins: RegExp;
gitSha?: string;
proxyPath?: string;
AAD_ENDPOINT: string;
@@ -30,12 +30,7 @@ interface ConfigContext {
// Default configuration
let configContext: Readonly<ConfigContext> = {
platform: Platform.Portal,
allowedParentFrameOrigins: [
`^https:\\/\\/cosmos.azure.(com|cn|us)$`,
`^https:\\/\\/[\\.\\w]+.portal.azure.(com|cn|us)$`,
`^https:\\/\\/[\\.\\w]+.ext.azure.(com|cn|us)$`,
`^https:\\/\\/[\\.\\w]+microsoftazure.de$`
],
allowedParentFrameOrigins: /^https:\/\/portal\.azure\.com$|^https:\/\/portal\.azure\.us$|^https:\/\/portal\.azure\.cn$|^https:\/\/portal\.microsoftazure\.de$|^https:\/\/.+\.portal\.azure\.com$|^https:\/\/.+\.portal\.azure\.us$|^https:\/\/.+\.portal\.azure\.cn$|^https:\/\/.+\.portal\.microsoftazure\.de$|^https:\/\/main\.documentdb\.ext\.azure\.com$|^https:\/\/main\.documentdb\.ext\.microsoftazure\.de$|^https:\/\/main\.documentdb\.ext\.azure\.cn$|^https:\/\/main\.documentdb\.ext\.azure\.us$/,
// Webpack injects this at build time
gitSha: process.env.GIT_SHA,
hostedExplorerURL: "https://cosmos.azure.com/",
@@ -78,13 +73,8 @@ export async function initializeConfiguration(): Promise<ConfigContext> {
const response = await fetch("./config.json");
if (response.status === 200) {
try {
const { allowedParentFrameOrigins, ...externalConfig } = await response.json();
const externalConfig = await response.json();
Object.assign(configContext, externalConfig);
if (allowedParentFrameOrigins && allowedParentFrameOrigins.length > 0) {
updateConfigContext({
allowedParentFrameOrigins: [...configContext.allowedParentFrameOrigins, ...allowedParentFrameOrigins]
});
}
} catch (error) {
console.error("Unable to parse json in config file");
console.error(error);

View File

@@ -86,7 +86,6 @@ export class DynamicListViewModel extends WaitsForTemplateViewModel {
public onRemoveItemKeyPress = (data: any, event: KeyboardEvent, source: any): boolean => {
if (event.keyCode === KeyCodes.Enter || event.keyCode === KeyCodes.Space) {
this.removeItem(data, event);
(document.querySelector(".dynamicListItem:last-of-type input") as HTMLElement).focus();
event.stopPropagation();
return false;
}
@@ -95,7 +94,7 @@ export class DynamicListViewModel extends WaitsForTemplateViewModel {
public addItem(): void {
this.listItems.push({ value: ko.observable("") });
(document.querySelector(".dynamicListItem:last-of-type input") as HTMLElement).focus();
document.getElementById("uniqueKeyItems").focus();
}
public onAddItemKeyPress = (source: any, event: KeyboardEvent): boolean => {

View File

@@ -115,10 +115,10 @@
<!-- Database provisioned throughput - Start -->
<!-- ko if: canConfigureThroughput -->
<div class="databaseProvision" aria-label="Provision database throughput"
<div class="databaseProvision" aria-label="New database provision support"
data-bind="visible: databaseCreateNew">
<input tabindex="0" type="checkbox" data-test="addCollectionPane-databaseSharedThroughput"
id="addCollection-databaseSharedThroughput" title="Provision database throughput"
id="addCollection-databaseSharedThroughput" title="Provision shared throughput"
data-bind="checked: databaseCreateNewShared" />
<span class="databaseProvisionText" for="databaseSharedThroughput">Provision database throughput</span>
<span class="infoTooltip" role="tooltip" tabindex="0">

View File

@@ -608,7 +608,7 @@ export default class AddCollectionPane extends ContextualPaneBase {
return true;
}
if (this.container.isPreferredApiMongoDB() && this.container.hasStorageAnalyticsAfecFeature()) {
if (this.container.isPreferredApiMongoDB()) {
return true;
}

View File

@@ -9,7 +9,6 @@ import Explorer from "../Explorer";
// TODO: Use specific actions for logging telemetry data
export abstract class ContextualPaneBase extends WaitsForTemplateViewModel {
private initalFocusedElement: HTMLElement | undefined;
public id: string;
public container: Explorer;
public firstFieldHasFocus: ko.Observable<boolean>;
@@ -50,11 +49,9 @@ export abstract class ContextualPaneBase extends WaitsForTemplateViewModel {
this.visible(false);
this.isExecuting(false);
this.resetData();
this.resetFocus();
}
public open() {
this.initalFocusedElement = document.activeElement as HTMLElement;
this.visible(true);
this.firstFieldHasFocus(true);
this.resizePane();
@@ -126,11 +123,4 @@ export abstract class ContextualPaneBase extends WaitsForTemplateViewModel {
$(paneElement).height(newPaneElementHeight);
}
private resetFocus(): void {
if (this.initalFocusedElement) {
this.initalFocusedElement.focus();
this.initalFocusedElement = undefined;
}
}
}

View File

@@ -67,7 +67,8 @@
name="collectionIdConfirmation"
required
class="collid"
data-bind="value: collectionIdConfirmation, hasFocus: firstFieldHasFocus, attr: { 'aria-label': collectionIdConfirmationText }"
data-bind="value: collectionIdConfirmation, hasFocus: firstFieldHasFocus"
aria-label="Confirm by typing the collection id"
/>
</p>
</div>

View File

@@ -80,7 +80,7 @@ export default class AddTableEntityPane extends TableEntityPane {
this.updateIsActionEnabled();
super.open();
}
const focusElement = document.getElementById("closeAddEntityPane");
const focusElement = document.getElementById("addTableEntityValue");
focusElement && focusElement.focus();
}

View File

@@ -21,7 +21,6 @@
<div class="firstdivbg headerline">
<span role="heading" aria-level="2" data-bind="text: title"></span>
<div
id="closeAddEntityPane"
class="closeImg"
role="button"
aria-label="Close pane"

View File

@@ -1,21 +0,0 @@
import { isInvalidParentFrameOrigin } from "./MessageValidation";
test.each`
domain | expected
${"https://cosmos.azure.com"} | ${false}
${"https://cosmos.azure.us"} | ${false}
${"https://cosmos.azure.cn"} | ${false}
${"https://cosmos.microsoftazure.de"} | ${false}
${"https://subdomain.portal.azure.com"} | ${false}
${"https://subdomain.portal.azure.us"} | ${false}
${"https://subdomain.portal.azure.cn"} | ${false}
${"https://subdomain.microsoftazure.de"} | ${false}
${"https://main.documentdb.ext.azure.com"} | ${false}
${"https://main.documentdb.ext.azure.us"} | ${false}
${"https://main.documentdb.ext.azure.cn"} | ${false}
${"https://main.documentdb.ext.microsoftazure.de"} | ${false}
${"https://random.domain"} | ${true}
${"https://malicious.cloudapp.azure.com"} | ${true}
`("returns $expected when called with $domain", ({ domain, expected }) => {
expect(isInvalidParentFrameOrigin({ origin: domain } as MessageEvent)).toBe(expected);
});

View File

@@ -4,18 +4,13 @@ export function isInvalidParentFrameOrigin(event: MessageEvent): boolean {
return !isValidOrigin(configContext.allowedParentFrameOrigins, event);
}
function isValidOrigin(allowedOrigins: string[], event: MessageEvent): boolean {
function isValidOrigin(allowedOrigins: RegExp, event: MessageEvent): boolean {
const eventOrigin = (event && event.origin) || "";
const windowOrigin = (window && window.origin) || "";
if (eventOrigin === windowOrigin) {
return true;
}
for (const origin of allowedOrigins) {
const result = new RegExp(origin).test(eventOrigin);
if (result) {
return true;
}
}
return false;
const result = allowedOrigins && allowedOrigins.test(eventOrigin);
return result;
}