diff --git a/site/src/pages/UserSettingsPage/SecurityPage/SingleSignOnSection.tsx b/site/src/pages/UserSettingsPage/SecurityPage/SingleSignOnSection.tsx index 224ad1422c0d4..4b0cecc6ffdc6 100644 --- a/site/src/pages/UserSettingsPage/SecurityPage/SingleSignOnSection.tsx +++ b/site/src/pages/UserSettingsPage/SecurityPage/SingleSignOnSection.tsx @@ -7,13 +7,21 @@ import KeyIcon from "@mui/icons-material/VpnKey"; import Button from "@mui/material/Button"; import Typography from "@mui/material/Typography"; import { convertToOAUTH } from "api/api"; -import { AuthMethods, LoginType, UserLoginType } from "api/typesGenerated"; -import Skeleton from "@mui/material/Skeleton"; +import { + AuthMethods, + LoginType, + OIDCAuthMethod, + UserLoginType, +} from "api/typesGenerated"; import { Stack } from "components/Stack/Stack"; import { useMutation } from "@tanstack/react-query"; import { ConfirmDialog } from "components/Dialogs/ConfirmDialog/ConfirmDialog"; import { getErrorMessage } from "api/errors"; import CheckCircleOutlined from "@mui/icons-material/CheckCircleOutlined"; +import { EmptyState } from "components/EmptyState/EmptyState"; +import { makeStyles } from "@mui/styles"; +import Link from "@mui/material/Link"; +import { docs } from "utils/docs"; type LoginTypeConfirmation = | { @@ -93,6 +101,32 @@ export const useSingleSignOnSection = () => { }; }; +const useEmptyStateStyles = makeStyles((theme) => ({ + root: { + minHeight: 0, + padding: theme.spacing(6, 4), + backgroundColor: theme.palette.background.paper, + borderRadius: theme.shape.borderRadius, + }, +})); + +function SSOEmptyState() { + const styles = useEmptyStateStyles(); + + return ( + + Learn how to add a provider + + } + /> + ); +} + type SingleSignOnSectionProps = ReturnType & { authMethods: AuthMethods; userLoginType: UserLoginType; @@ -108,6 +142,12 @@ export const SingleSignOnSection = ({ isConfirming, error, }: SingleSignOnSectionProps) => { + const authList = Object.values( + authMethods, + ) as (typeof authMethods)[keyof typeof authMethods][]; + + const noSsoEnabled = !authList.some((method) => method.enabled); + return ( <>
- {authMethods && userLoginType ? ( - userLoginType.login_type === "password" ? ( - <> - {authMethods.github.enabled && ( - - )} - {authMethods.oidc.enabled && ( - - )} - - ) : ( - + {authMethods.github.enabled && ( + + )} + + {authMethods.oidc.enabled && ( + + )} + + {noSsoEnabled && } + + ) : ( + theme.palette.background.paper, + borderRadius: 1, + border: (theme) => `1px solid ${theme.palette.divider}`, + padding: 2, + display: "flex", + gap: 2, + alignItems: "center", + fontSize: 14, + }} + > + theme.palette.background.paper, - borderRadius: 1, - border: (theme) => `1px solid ${theme.palette.divider}`, - padding: 2, - display: "flex", - gap: 2, - alignItems: "center", - fontSize: 14, + color: (theme) => theme.palette.success.light, + fontSize: 16, }} - > - theme.palette.success.light, - fontSize: 16, - }} - /> - - Authenticated with{" "} - - {userLoginType.login_type === "github" - ? "GitHub" - : getOIDCLabel(authMethods)} - - - - {userLoginType.login_type === "github" ? ( - - ) : ( - - )} - + /> + + Authenticated with{" "} + + {userLoginType.login_type === "github" + ? "GitHub" + : getOIDCLabel(authMethods.oidc)} + + + + {userLoginType.login_type === "github" ? ( + + ) : ( + + )} - ) - ) : ( - + )}
@@ -198,21 +234,23 @@ export const SingleSignOnSection = ({ ); }; -const OIDCIcon = ({ authMethods }: { authMethods: AuthMethods }) => { - return authMethods.oidc.iconUrl ? ( +const OIDCIcon = ({ oidcAuth }: { oidcAuth: OIDCAuthMethod }) => { + if (!oidcAuth.iconUrl) { + return ; + } + + return ( - ) : ( - ); }; -const getOIDCLabel = (authMethods: AuthMethods) => { - return authMethods.oidc.signInText || "OpenID Connect"; +const getOIDCLabel = (oidcAuth: OIDCAuthMethod) => { + return oidcAuth.signInText || "OpenID Connect"; }; const ConfirmLoginTypeChangeModal = ({