Skip to content

Commit 0069b74

Browse files
atrakhConvex, Inc.
authored andcommitted
dashboard: show instructions if a team requires sso login (#42689)
When we detect that login with SSO is required for a team, show a UI with instructions on what the user should do next. GitOrigin-RevId: c124f64cd80db870e37cf890aa80d6acdb6efdf5
1 parent 472c7c8 commit 0069b74

File tree

2 files changed

+47
-3
lines changed

2 files changed

+47
-3
lines changed

npm-packages/dashboard/src/api/api.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { SWRConfiguration } from "swr";
1414
import { useAccessToken } from "hooks/useServerSideData";
1515
import { useRouter } from "next/router";
1616
import { useCallback, useEffect } from "react";
17-
import { usePrevious } from "react-use";
17+
import { createGlobalState, usePrevious } from "react-use";
1818
import { captureException } from "@sentry/nextjs";
1919
import { getGoogleAnalyticsClientId, reportHttpError } from "../hooks/fetching";
2020
import { forceCheckIsOnline } from "./onlineStatus";
@@ -36,6 +36,8 @@ export const useMutate = createMutateHook(client, "big-brain", isMatch);
3636

3737
type Path<M extends "post" | "put" | "get"> = PathsWithMethod<BigBrainPaths, M>;
3838

39+
export const useSSOLoginRequired = createGlobalState<string>();
40+
3941
export function useBBQuery<QueryPath extends Path<"get">>({
4042
path,
4143
pathParams,
@@ -45,8 +47,11 @@ export function useBBQuery<QueryPath extends Path<"get">>({
4547
path: QueryPath;
4648
pathParams: BigBrainPaths[QueryPath]["get"]["parameters"]["path"];
4749
queryParams?: BigBrainPaths[QueryPath]["get"]["parameters"]["query"];
48-
swrOptions?: SWRConfiguration;
50+
swrOptions?: Omit<SWRConfiguration, "onError">;
4951
}) {
52+
const router = useRouter();
53+
const [ssoLoginRequired, setSSOLoginRequired] = useSSOLoginRequired();
54+
5055
const googleAnalyticsId =
5156
typeof document !== "undefined" &&
5257
getGoogleAnalyticsClientId(document.cookie);
@@ -86,6 +91,11 @@ export function useBBQuery<QueryPath extends Path<"get">>({
8691
const res = useQuery(path, requestOptions, {
8792
keepPreviousData: true,
8893
isPaused: () => paused,
94+
onError: (e) => {
95+
if ((e as any).code === "SSORequired" && !ssoLoginRequired) {
96+
setSSOLoginRequired(router.query.team as string);
97+
}
98+
},
8999
...swrOptions,
90100
});
91101
if ("error" in res && !!res.error && typeof res.error === "object") {

npm-packages/dashboard/src/pages/_app.tsx

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ import { UIProvider } from "@ui/UIContext";
3232
import Link from "next/link";
3333
import { RefreshSession } from "components/login/RefreshSession";
3434
import { AuthProvider } from "providers/AuthProvider";
35+
import { useSSOLoginRequired } from "api/api";
36+
import { Sheet } from "@ui/Sheet";
37+
import { Button } from "@ui/Button";
38+
import { ExitIcon, LockClosedIcon } from "@radix-ui/react-icons";
3539

3640
declare global {
3741
interface Window {
@@ -52,6 +56,7 @@ const UNAUTHED_ROUTES = [
5256
];
5357

5458
export default function App({ Component, pageProps }: AppProps) {
59+
const [ssoLoginRequired] = useSSOLoginRequired();
5560
const router = useRouter();
5661
const pathWithoutQueryString = router.asPath.split("?")[0].split("#")[0];
5762

@@ -102,7 +107,36 @@ export default function App({ Component, pageProps }: AppProps) {
102107
<div className="flex h-screen flex-col">
103108
<CommandPalette />
104109
<DashboardHeader />
105-
{inDeployment ? (
110+
{!!ssoLoginRequired &&
111+
ssoLoginRequired === router.query.team ? (
112+
<div className="flex h-full w-full items-center justify-center">
113+
<Sheet className="flex max-w-prose flex-col gap-4">
114+
<div className="flex items-center gap-2">
115+
<LockClosedIcon className="size-8" />
116+
<h3>Single Sign-On Login Required</h3>
117+
</div>
118+
<span className="flex flex-col gap-2">
119+
<p>
120+
This team requires you to log in with
121+
Single Sign-On to access it.
122+
</p>
123+
<p>
124+
You may log out and log back in through
125+
your Single Sign-On provider, or switch
126+
teams by using the selector on the top
127+
of this page.
128+
</p>
129+
</span>
130+
<Button
131+
className="ml-auto w-fit"
132+
href="/api/auth/logout"
133+
icon={<ExitIcon />}
134+
>
135+
Log Out
136+
</Button>
137+
</Sheet>
138+
</div>
139+
) : inDeployment ? (
106140
<DeploymentInfoProvider>
107141
<MaybeDeploymentApiProvider>
108142
<CurrentDeploymentDashboardLayout>

0 commit comments

Comments
 (0)