New preview site (#2036)

* Changes to DE preview site to support managed identity. Changes to
infrastructure to use new preview site.

* Fix formatting.

* Potential fix for code scanning alert no. 56: Server-side request forgery

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* Use different secrets for subscription/tenant/client id's.

* Revert new id names.

* Update Az CLI config.

* Update to Node 18 and update security vulnerable dependencies.

---------

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
This commit is contained in:
jawelton74 2025-01-30 16:14:03 -08:00 committed by GitHub
parent 7015590d1a
commit 881726e9af
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 1016 additions and 435 deletions

View File

@ -1 +1 @@
[Preview this branch](https://cosmos-explorer-preview.azurewebsites.net/pull/EDIT_THIS_NUMBER_IN_THE_PR_DESCRIPTION?feature.someFeatureFlagYouMightNeed=true) [Preview this branch](https://dataexplorer-preview.azurewebsites.net/pull/EDIT_THIS_NUMBER_IN_THE_PR_DESCRIPTION?feature.someFeatureFlagYouMightNeed=true)

View File

@ -96,14 +96,16 @@ jobs:
with: with:
name: dist name: dist
path: dist/ path: dist/
- name: "Az CLI login"
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.PREVIEW_SUBSCRIPTION_ID }}
- name: Upload build to preview blob storage - name: Upload build to preview blob storage
run: az storage blob upload-batch -d '$web' -s 'dist' --account-name cosmosexplorerpreview --destination-path "${{github.event.pull_request.head.sha || github.sha}}" --account-key="${PREVIEW_STORAGE_KEY}" --overwrite true run: az storage blob upload-batch -d '$web' -s 'dist' --account-name ${{ secrets.PREVIEW_STORAGE_ACCOUNT_NAME }} --destination-path "${{github.event.pull_request.head.sha || github.sha}}" --auth-mode login --overwrite true
env:
PREVIEW_STORAGE_KEY: ${{ secrets.PREVIEW_STORAGE_KEY }}
- name: Upload preview config to blob storage - name: Upload preview config to blob storage
run: az storage blob upload -c '$web' -f ./preview/config.json --account-name cosmosexplorerpreview --name "${{github.event.pull_request.head.sha || github.sha}}/config.json" --account-key="${PREVIEW_STORAGE_KEY}" --overwrite true run: az storage blob upload -c '$web' -f ./preview/config.json --account-name ${{ secrets.PREVIEW_STORAGE_ACCOUNT_NAME }} --name "${{github.event.pull_request.head.sha || github.sha}}/config.json" --auth-mode login --overwrite true
env:
PREVIEW_STORAGE_KEY: ${{ secrets.PREVIEW_STORAGE_KEY }}
nuget: nuget:
name: Publish Nuget name: Publish Nuget
if: github.ref == 'refs/heads/master' || contains(github.ref, 'hotfix/') || contains(github.ref, 'release/') if: github.ref == 'refs/heads/master' || contains(github.ref, 'hotfix/') || contains(github.ref, 'release/')

View File

@ -1,7 +1,7 @@
[defaults] [defaults]
group = stfaul group = dataexplorer-preview
sku = P1v2 sku = P1V2
appserviceplan = stfaul_asp_Linux_centralus_0 appserviceplan = dataexplorer-preview
location = centralus location = westus2
web = cosmos-explorer-preview web = dataexplorer-preview

View File

@ -4,8 +4,8 @@ Cosmos Explorer Preview makes it possible to try a working version of any commit
Initial support is for Hosted (Connection string only) or the Azure Portal. Examples: Initial support is for Hosted (Connection string only) or the Azure Portal. Examples:
Connection string URLs: https://cosmos-explorer-preview.azurewebsites.net/commit/COMMIT_SHA/hostedExplorer.html Connection string URLs: https://dataexplorer-preview.azurewebsites.net/commit/COMMIT_SHA/hostedExplorer.html
Portal URLs: https://ms.portal.azure.com/?dataExplorerSource=https://cosmos-explorer-preview.azurewebsites.net/commit/COMMIT_SHA/explorer.html#home Portal URLs: https://ms.portal.azure.com/?dataExplorerSource=https://dataexplorer-preview.azurewebsites.net/commit/COMMIT_SHA/explorer.html#home
In both cases replace `COMMIT_SHA` with the commit you want to view. It must have already completed its build on GitHub Actions. In both cases replace `COMMIT_SHA` with the commit you want to view. It must have already completed its build on GitHub Actions.

View File

@ -1,4 +1,4 @@
{ {
"PROXY_PATH": "/proxy", "PROXY_PATH": "/proxy",
"msalRedirectURI": "https://cosmos-explorer-preview.azurewebsites.net/" "msalRedirectURI": "https://dataexplorer-preview.azurewebsites.net/"
} }

View File

@ -3,8 +3,15 @@ const { createProxyMiddleware } = require("http-proxy-middleware");
const port = process.env.PORT || 3000; const port = process.env.PORT || 3000;
const fetch = require("node-fetch"); const fetch = require("node-fetch");
const api = createProxyMiddleware("/api", { const backendEndpoint = "https://cdb-ms-mpac-pbe.cosmos.azure.com";
target: "https://cdb-ms-mpac-pbe.cosmos.azure.com", const previewSiteEndpoint = "https://dataexplorer-preview.azurewebsites.net";
const previewStorageWebsiteEndpoint = "https://dataexplorerpreview.z5.web.core.windows.net/";
const githubApiUrl = "https://api.github.com/repos/Azure/cosmos-explorer";
const githubPullRequestUrl = "https://github.com/Azure/cosmos-explorer/pull";
const azurePortalMpacEndpoint = "https://ms.portal.azure.com/";
const api = createProxyMiddleware({
target: backendEndpoint,
changeOrigin: true, changeOrigin: true,
logLevel: "debug", logLevel: "debug",
bypass: (req, res) => { bypass: (req, res) => {
@ -15,8 +22,8 @@ const api = createProxyMiddleware("/api", {
}, },
}); });
const proxy = createProxyMiddleware("/proxy", { const proxy = createProxyMiddleware({
target: "https://cdb-ms-mpac-pbe.cosmos.azure.com", target: backendEndpoint,
changeOrigin: true, changeOrigin: true,
secure: false, secure: false,
logLevel: "debug", logLevel: "debug",
@ -27,35 +34,38 @@ const proxy = createProxyMiddleware("/proxy", {
}, },
}); });
const commit = createProxyMiddleware("/commit", { const commit = createProxyMiddleware({
target: "https://cosmosexplorerpreview.blob.core.windows.net", target: previewStorageWebsiteEndpoint,
changeOrigin: true, changeOrigin: true,
secure: false, secure: false,
logLevel: "debug", logLevel: "debug",
pathRewrite: { "^/commit": "$web/" }, pathRewrite: { "^/commit": "/" },
}); });
const app = express(); const app = express();
app.use(api); app.use("/api", api);
app.use(proxy); app.use("/proxy", proxy);
app.use(commit); app.use("/commit", commit);
app.get("/pull/:pr(\\d+)", (req, res) => { app.get("/pull/:pr(\\d+)", (req, res) => {
const pr = req.params.pr; const pr = req.params.pr;
if (!/^\d+$/.test(pr)) {
return res.status(400).send("Invalid pull request number");
}
const [, query] = req.originalUrl.split("?"); const [, query] = req.originalUrl.split("?");
const search = new URLSearchParams(query); const search = new URLSearchParams(query);
fetch("https://api.github.com/repos/Azure/cosmos-explorer/pulls/" + pr) fetch(`${githubApiUrl}/pulls/${pr}`)
.then((response) => response.json()) .then((response) => response.json())
.then(({ head: { ref, sha } }) => { .then(({ head: { ref, sha } }) => {
const prUrl = new URL("https://github.com/Azure/cosmos-explorer/pull/" + pr); const prUrl = new URL(`${githubPullRequestUrl}/${pr}`);
prUrl.hash = ref; prUrl.hash = ref;
search.set("feature.pr", prUrl.href); search.set("feature.pr", prUrl.href);
const explorer = new URL("https://cosmos-explorer-preview.azurewebsites.net/commit/" + sha + "/explorer.html"); const explorer = new URL(`${previewSiteEndpoint}/commit/${sha}/explorer.html`);
explorer.search = search.toString(); explorer.search = search.toString();
const portal = new URL("https://ms.portal.azure.com/"); const portal = new URL(azurePortalMpacEndpoint);
portal.searchParams.set("dataExplorerSource", explorer.href); portal.searchParams.set("dataExplorerSource", explorer.href);
return res.redirect(portal.href); return res.redirect(portal.href);
@ -63,12 +73,10 @@ app.get("/pull/:pr(\\d+)", (req, res) => {
.catch(() => res.sendStatus(500)); .catch(() => res.sendStatus(500));
}); });
app.get("/", (req, res) => { app.get("/", (req, res) => {
fetch("https://api.github.com/repos/Azure/cosmos-explorer/branches/master") fetch(`${githubApiUrl}/branches/master`)
.then((response) => response.json()) .then((response) => response.json())
.then(({ commit: { sha } }) => { .then(({ commit: { sha } }) => {
const explorer = new URL( const explorer = new URL(`${previewSiteEndpoint}/commit/${sha}/hostedExplorer.html`);
"https://cosmos-explorer-preview.azurewebsites.net/commit/" + sha + "/hostedExplorer.html"
);
return res.redirect(explorer.href); return res.redirect(explorer.href);
}) })
.catch(() => res.sendStatus(500)); .catch(() => res.sendStatus(500));

1360
preview/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"deploy": "az webapp up --name \"cosmos-explorer-preview\" --subscription \"cosmosdb-portalteam-generaltest-msft\" --resource-group \"stfaul\"", "deploy": "az webapp up --name \"dataexplorer-preview\" --subscription \"cosmosdb-portalteam-runners\" --resource-group \"dataexplorer-preview\" --runtime \"NODE:18-lts\" --sku P1V2",
"start": "node index.js", "start": "node index.js",
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"
}, },
@ -12,7 +12,8 @@
"author": "Microsoft Corporation", "author": "Microsoft Corporation",
"dependencies": { "dependencies": {
"express": "^4.17.1", "express": "^4.17.1",
"http-proxy-middleware": "^1.1.0", "http-proxy-middleware": "^3.0.3",
"node": "^18.20.6",
"node-fetch": "^2.6.1" "node-fetch": "^2.6.1"
} }
} }

View File

@ -91,7 +91,7 @@ let configContext: Readonly<ConfigContext> = {
`^https:\\/\\/.*\\.analysis-df\\.net$`, `^https:\\/\\/.*\\.analysis-df\\.net$`,
`^https:\\/\\/.*\\.analysis-df\\.windows\\.net$`, `^https:\\/\\/.*\\.analysis-df\\.windows\\.net$`,
`^https:\\/\\/.*\\.azure-test\\.net$`, `^https:\\/\\/.*\\.azure-test\\.net$`,
`^https:\\/\\/cosmos-explorer-preview\\.azurewebsites\\.net$`, `^https:\\/\\/dataexplorer-preview\\.azurewebsites\\.net$`,
], // Webpack injects this at build time ], // Webpack injects this at build time
gitSha: process.env.GIT_SHA, gitSha: process.env.GIT_SHA,
hostedExplorerURL: "https://cosmos.azure.com/", hostedExplorerURL: "https://cosmos.azure.com/",

View File

@ -141,9 +141,7 @@ export const allowedArcadiaEndpoints: ReadonlyArray<string> = ["https://workspac
export const allowedHostedExplorerEndpoints: ReadonlyArray<string> = ["https://cosmos.azure.com/"]; export const allowedHostedExplorerEndpoints: ReadonlyArray<string> = ["https://cosmos.azure.com/"];
export const allowedMsalRedirectEndpoints: ReadonlyArray<string> = [ export const allowedMsalRedirectEndpoints: ReadonlyArray<string> = ["https://dataexplorer-preview.azurewebsites.net/"];
"https://cosmos-explorer-preview.azurewebsites.net/",
];
export const allowedJunoOrigins: ReadonlyArray<string> = [ export const allowedJunoOrigins: ReadonlyArray<string> = [
JunoEndpoints.Test, JunoEndpoints.Test,

View File

@ -30,7 +30,7 @@
<clear /> <clear />
<add name="X-Xss-Protection" value="1; mode=block" /> <add name="X-Xss-Protection" value="1; mode=block" />
<add name="X-Content-Type-Options" value="nosniff" /> <add name="X-Content-Type-Options" value="nosniff" />
<add name="Content-Security-Policy" value="frame-ancestors 'self' portal.azure.com *.portal.azure.com portal.azure.us portal.azure.cn portal.microsoftazure.de df.onecloud.azure-test.net *.fabric.microsoft.com *.powerbi.com *.analysis-df.windows.net cosmos-explorer-preview.azurewebsites.net" /> <add name="Content-Security-Policy" value="frame-ancestors 'self' portal.azure.com *.portal.azure.com portal.azure.us portal.azure.cn portal.microsoftazure.de df.onecloud.azure-test.net *.fabric.microsoft.com *.powerbi.com *.analysis-df.windows.net dataexplorer-preview.azurewebsites.net" />
</customHeaders> </customHeaders>
<redirectHeaders> <redirectHeaders>
<clear /> <clear />