mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2024-11-29 08:56:52 +00:00
stuck in a redirect loop, need to work that out
This commit is contained in:
parent
06d4829422
commit
4866d3c902
@ -238,6 +238,15 @@ export async function initializeConfiguration(): Promise<ConfigContext> {
|
|||||||
updateConfigContext({ platform });
|
updateConfigContext({ platform });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (window.location.origin !== configContext.hostedExplorerURL) {
|
||||||
|
if (window.location.origin === "https://localhost:1234") {
|
||||||
|
// Special case for localhost, we need to send them to 'hostedExplorer.html'.
|
||||||
|
updateConfigContext({ hostedExplorerURL: "https://localhost:1234/hostedExplorer.html" });
|
||||||
|
} else {
|
||||||
|
const newOrigin = window.location.origin.endsWith("/") ? window.location.origin : `${window.location.origin}/`;
|
||||||
|
updateConfigContext({ hostedExplorerURL: newOrigin });
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("No configuration file found using defaults");
|
console.error("No configuration file found using defaults");
|
||||||
}
|
}
|
||||||
@ -245,3 +254,4 @@ export async function initializeConfiguration(): Promise<ConfigContext> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export { configContext };
|
export { configContext };
|
||||||
|
|
||||||
|
@ -1,20 +1,40 @@
|
|||||||
import { PrimaryButton, Stack, Text } from "@fluentui/react";
|
import { PrimaryButton, Stack, Text } from "@fluentui/react";
|
||||||
|
import { AuthType } from "AuthType";
|
||||||
|
import { configContext } from "ConfigContext";
|
||||||
|
import { userContext } from "UserContext";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
|
||||||
export const OpenFullScreen: React.FunctionComponent = () => {
|
export const OpenFullScreen: React.FunctionComponent = () => {
|
||||||
|
const searchParams = new URLSearchParams();
|
||||||
|
let hasAccountContext = false;
|
||||||
|
let requiresConnectionString = false;
|
||||||
|
|
||||||
|
if (userContext.authType === AuthType.AAD) {
|
||||||
|
if (userContext.subscriptionId && userContext.databaseAccount) {
|
||||||
|
searchParams.append("subscription", userContext.subscriptionId);
|
||||||
|
searchParams.append("account", userContext.databaseAccount.id);
|
||||||
|
searchParams.append("authType", "entra");
|
||||||
|
hasAccountContext = true;
|
||||||
|
}
|
||||||
|
} else if (userContext.authType === AuthType.MasterKey || userContext.authType === AuthType.ResourceToken) {
|
||||||
|
searchParams.append("authType", "connectionstring")
|
||||||
|
requiresConnectionString = true;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div style={{ padding: "34px" }}>
|
<div style={{ padding: "34px" }}>
|
||||||
<Stack tokens={{ childrenGap: 10 }}>
|
<Stack tokens={{ childrenGap: 10 }}>
|
||||||
<Text>
|
<Text>
|
||||||
Open this database account in a new browser tab with Cosmos DB Explorer. You can connect using your
|
Open this database account in a new browser tab with Cosmos DB Explorer.
|
||||||
Microsoft account or a connection string.
|
{requiresConnectionString && " You'll need to provide a connection string."}
|
||||||
|
{hasAccountContext && " You may be prompted to sign in with Entra ID, and then you'll be redirected back to this account."}
|
||||||
|
Open tabs and queries will not be carried over, but will remain in this tab.
|
||||||
</Text>
|
</Text>
|
||||||
<Stack horizontal tokens={{ childrenGap: 10 }}>
|
<Stack horizontal tokens={{ childrenGap: 10 }}>
|
||||||
<PrimaryButton
|
<PrimaryButton
|
||||||
onClick={() => {
|
href={`${configContext.hostedExplorerURL}?${searchParams.toString()}`}
|
||||||
window.open("https://cosmos.azure.com/", "_blank");
|
target="_blank"
|
||||||
}}
|
|
||||||
text="Open"
|
text="Open"
|
||||||
iconProps={{ iconName: "OpenInNewWindow" }}
|
iconProps={{ iconName: "OpenInNewWindow" }}
|
||||||
/>
|
/>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { initializeIcons } from "@fluentui/react";
|
import { initializeIcons } from "@fluentui/react";
|
||||||
import { useBoolean } from "@fluentui/react-hooks";
|
import { useBoolean } from "@fluentui/react-hooks";
|
||||||
import { AadAuthorizationFailure } from "Platform/Hosted/Components/AadAuthorizationFailure";
|
import { AadAuthorizationFailure } from "Platform/Hosted/Components/AadAuthorizationFailure";
|
||||||
|
import { getMsalInstance } from "Utils/AuthorizationUtils";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { render } from "react-dom";
|
import { render } from "react-dom";
|
||||||
import ChevronRight from "../images/chevron-right.svg";
|
import ChevronRight from "../images/chevron-right.svg";
|
||||||
@ -42,6 +43,23 @@ const App: React.FunctionComponent = () => {
|
|||||||
const ref = React.useRef<HTMLIFrameElement>();
|
const ref = React.useRef<HTMLIFrameElement>();
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
const params = new URLSearchParams(window.location.search);
|
||||||
|
if (params.get("authType") === "entra") {
|
||||||
|
const msalInstance = await getMsalInstance();
|
||||||
|
const response = await msalInstance.handleRedirectPromise();
|
||||||
|
if (response) {
|
||||||
|
console.log("Redirect Promise Response", response);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Send the user to log in immediately
|
||||||
|
console.log("Starting non-interactive login");
|
||||||
|
login(false);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
// If ref.current is undefined no iframe has been rendered
|
// If ref.current is undefined no iframe has been rendered
|
||||||
if (ref.current) {
|
if (ref.current) {
|
||||||
// In hosted mode, we can set global properties directly on the child iframe.
|
// In hosted mode, we can set global properties directly on the child iframe.
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import React, { useState } from "react";
|
import { getMsalInstance } from "Utils/AuthorizationUtils";
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom";
|
||||||
import Arrow from "../images/Arrow.svg";
|
import Arrow from "../images/Arrow.svg";
|
||||||
import CosmosDB_20170829 from "../images/CosmosDB_20170829.svg";
|
import CosmosDB_20170829 from "../images/CosmosDB_20170829.svg";
|
||||||
@ -9,11 +10,18 @@ import "../less/index.less";
|
|||||||
|
|
||||||
const Index = (): JSX.Element => {
|
const Index = (): JSX.Element => {
|
||||||
const [navigationSelection, setNavigationSelection] = useState("quickstart");
|
const [navigationSelection, setNavigationSelection] = useState("quickstart");
|
||||||
|
|
||||||
const quickstart_click = () => {
|
const quickstart_click = () => {
|
||||||
setNavigationSelection("quickstart");
|
setNavigationSelection("quickstart");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
const msalInstance = await getMsalInstance();
|
||||||
|
console.log("handleRedirectPromise");
|
||||||
|
await msalInstance.handleRedirectPromise();
|
||||||
|
})();
|
||||||
|
}, []);
|
||||||
|
|
||||||
const explorer_click = () => {
|
const explorer_click = () => {
|
||||||
setNavigationSelection("explorer");
|
setNavigationSelection("explorer");
|
||||||
};
|
};
|
||||||
|
@ -13,12 +13,12 @@ import { CollectionCreation, CollectionCreationDefaults } from "./Shared/Constan
|
|||||||
interface ThroughputDefaults {
|
interface ThroughputDefaults {
|
||||||
fixed: number;
|
fixed: number;
|
||||||
unlimited:
|
unlimited:
|
||||||
| number
|
| number
|
||||||
| {
|
| {
|
||||||
collectionThreshold: number;
|
collectionThreshold: number;
|
||||||
lessThanOrEqualToThreshold: number;
|
lessThanOrEqualToThreshold: number;
|
||||||
greatThanThreshold: number;
|
greatThanThreshold: number;
|
||||||
};
|
};
|
||||||
unlimitedmax: number;
|
unlimitedmax: number;
|
||||||
unlimitedmin: number;
|
unlimitedmin: number;
|
||||||
shared: number;
|
shared: number;
|
||||||
@ -192,3 +192,4 @@ function apiType(account: DatabaseAccount | undefined): ApiType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export { updateUserContext, userContext };
|
export { updateUserContext, userContext };
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ export const allowedGraphEndpoints: ReadonlyArray<string> = ["https://graph.micr
|
|||||||
|
|
||||||
export const allowedArcadiaEndpoints: ReadonlyArray<string> = ["https://workspaceartifacts.projectarcadia.net"];
|
export const allowedArcadiaEndpoints: ReadonlyArray<string> = ["https://workspaceartifacts.projectarcadia.net"];
|
||||||
|
|
||||||
export const allowedHostedExplorerEndpoints: ReadonlyArray<string> = ["https://cosmos.azure.com/"];
|
export const allowedHostedExplorerEndpoints: ReadonlyArray<string> = ["https://cosmos.azure.com/", "https://localhost:1234/"];
|
||||||
|
|
||||||
export const allowedMsalRedirectEndpoints: ReadonlyArray<string> = [
|
export const allowedMsalRedirectEndpoints: ReadonlyArray<string> = [
|
||||||
"https://cosmos-explorer-preview.azurewebsites.net/",
|
"https://cosmos-explorer-preview.azurewebsites.net/",
|
||||||
|
@ -13,7 +13,7 @@ interface ReturnType {
|
|||||||
isLoggedIn: boolean;
|
isLoggedIn: boolean;
|
||||||
graphToken: string;
|
graphToken: string;
|
||||||
armToken: string;
|
armToken: string;
|
||||||
login: () => void;
|
login: (userTriggered?: boolean) => void;
|
||||||
logout: () => void;
|
logout: () => void;
|
||||||
tenantId: string;
|
tenantId: string;
|
||||||
account: msal.AccountInfo;
|
account: msal.AccountInfo;
|
||||||
@ -37,8 +37,21 @@ export function useAADAuth(): ReturnType {
|
|||||||
const [armToken, setArmToken] = React.useState<string>();
|
const [armToken, setArmToken] = React.useState<string>();
|
||||||
const [authFailure, setAuthFailure] = React.useState<AadAuthFailure>(undefined);
|
const [authFailure, setAuthFailure] = React.useState<AadAuthFailure>(undefined);
|
||||||
|
|
||||||
|
console.log("Current AAD State", {
|
||||||
|
isLoggedIn, account, tenantId
|
||||||
|
});
|
||||||
|
|
||||||
msalInstance.setActiveAccount(account);
|
msalInstance.setActiveAccount(account);
|
||||||
const login = React.useCallback(async () => {
|
const login = React.useCallback(async (userTriggered: boolean = true) => {
|
||||||
|
if (!userTriggered) {
|
||||||
|
console.log("Starting non-interactive login");
|
||||||
|
// If the user didn't trigger the login, we don't want to pop up the login dialog
|
||||||
|
await msalInstance.acquireTokenRedirect({
|
||||||
|
redirectUri: configContext.msalRedirectURI,
|
||||||
|
scopes: [],
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
const response = await msalInstance.loginPopup({
|
const response = await msalInstance.loginPopup({
|
||||||
redirectUri: configContext.msalRedirectURI,
|
redirectUri: configContext.msalRedirectURI,
|
||||||
scopes: [],
|
scopes: [],
|
||||||
@ -47,13 +60,13 @@ export function useAADAuth(): ReturnType {
|
|||||||
setAccount(response.account);
|
setAccount(response.account);
|
||||||
setTenantId(response.tenantId);
|
setTenantId(response.tenantId);
|
||||||
localStorage.setItem("cachedTenantId", response.tenantId);
|
localStorage.setItem("cachedTenantId", response.tenantId);
|
||||||
}, []);
|
}, [setLoggedIn, setAccount, setTenantId]);
|
||||||
|
|
||||||
const logout = React.useCallback(() => {
|
const logout = React.useCallback(() => {
|
||||||
setLoggedOut();
|
setLoggedOut();
|
||||||
localStorage.removeItem("cachedTenantId");
|
localStorage.removeItem("cachedTenantId");
|
||||||
msalInstance.logoutRedirect();
|
msalInstance.logoutRedirect();
|
||||||
}, []);
|
}, [setLoggedOut]);
|
||||||
|
|
||||||
const switchTenant = React.useCallback(
|
const switchTenant = React.useCallback(
|
||||||
async (id) => {
|
async (id) => {
|
||||||
@ -66,7 +79,7 @@ export function useAADAuth(): ReturnType {
|
|||||||
setAccount(response.account);
|
setAccount(response.account);
|
||||||
localStorage.setItem("cachedTenantId", response.tenantId);
|
localStorage.setItem("cachedTenantId", response.tenantId);
|
||||||
},
|
},
|
||||||
[account, tenantId],
|
[setTenantId, setAccount],
|
||||||
);
|
);
|
||||||
|
|
||||||
const acquireTokens = React.useCallback(async () => {
|
const acquireTokens = React.useCallback(async () => {
|
||||||
@ -123,6 +136,19 @@ export function useAADAuth(): ReturnType {
|
|||||||
}
|
}
|
||||||
}, [account, tenantId, acquireTokens, authFailure]);
|
}, [account, tenantId, acquireTokens, authFailure]);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
// If we're on a redirect, handle it
|
||||||
|
const response = await msalInstance.handleRedirectPromise();
|
||||||
|
if (response) {
|
||||||
|
setLoggedIn();
|
||||||
|
setAccount(response.account);
|
||||||
|
setTenantId(response.tenantId);
|
||||||
|
localStorage.setItem("cachedTenantId", response.tenantId);
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
}, [setLoggedIn])
|
||||||
|
|
||||||
return {
|
return {
|
||||||
account,
|
account,
|
||||||
tenantId,
|
tenantId,
|
||||||
|
Loading…
Reference in New Issue
Block a user