From 63eae352ee2a09eae2e5bd1521f97128bf38462a Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Thu, 4 Jan 2024 20:12:28 -0500 Subject: [PATCH] Auto-redirect single auth provider OIDC installations to login closes #6167 --- .../components/AuthenticationProvider.tsx | 25 ++----------------- app/scenes/Login/getRedirectUrl.ts | 25 +++++++++++++++++++ app/scenes/Login/index.tsx | 7 ++++++ 3 files changed, 34 insertions(+), 23 deletions(-) create mode 100644 app/scenes/Login/getRedirectUrl.ts diff --git a/app/scenes/Login/components/AuthenticationProvider.tsx b/app/scenes/Login/components/AuthenticationProvider.tsx index af218c06c..5d564453d 100644 --- a/app/scenes/Login/components/AuthenticationProvider.tsx +++ b/app/scenes/Login/components/AuthenticationProvider.tsx @@ -2,14 +2,12 @@ import { EmailIcon } from "outline-icons"; import * as React from "react"; import { useTranslation } from "react-i18next"; import styled from "styled-components"; -import { Client } from "@shared/types"; -import { parseDomain } from "@shared/utils/domains"; import ButtonLarge from "~/components/ButtonLarge"; import InputLarge from "~/components/InputLarge"; import PluginIcon from "~/components/PluginIcon"; -import env from "~/env"; import { client } from "~/utils/ApiClient"; import Desktop from "~/utils/Desktop"; +import { getRedirectUrl } from "../getRedirectUrl"; type Props = { id: string; @@ -19,25 +17,6 @@ type Props = { onEmailSuccess: (email: string) => void; }; -function useRedirectHref(authUrl: string) { - // If we're on a custom domain or a subdomain then the auth must point to the - // apex (env.URL) for authentication so that the state cookie can be set and read. - // We pass the host into the auth URL so that the server can redirect on error - // and keep the user on the same page. - const { custom, teamSubdomain, host } = parseDomain(window.location.origin); - const url = new URL(env.URL); - url.pathname = authUrl; - - if (custom || teamSubdomain) { - url.searchParams.set("host", host); - } - if (Desktop.isElectron()) { - url.searchParams.set("client", Client.Desktop); - } - - return url.toString(); -} - function AuthenticationProvider(props: Props) { const { t } = useTranslation(); const [showEmailSignin, setShowEmailSignin] = React.useState(false); @@ -76,7 +55,7 @@ function AuthenticationProvider(props: Props) { } }; - const href = useRedirectHref(authUrl); + const href = getRedirectUrl(authUrl); if (id === "email") { if (isCreate) { diff --git a/app/scenes/Login/getRedirectUrl.ts b/app/scenes/Login/getRedirectUrl.ts new file mode 100644 index 000000000..e5039a956 --- /dev/null +++ b/app/scenes/Login/getRedirectUrl.ts @@ -0,0 +1,25 @@ +import { Client } from "@shared/types"; +import { parseDomain } from "@shared/utils/domains"; +import env from "~/env"; +import Desktop from "~/utils/Desktop"; + +/** + * If we're on a custom domain or a subdomain then the auth must point to the + * apex (env.URL) for authentication so that the state cookie can be set and read. + * We pass the host into the auth URL so that the server can redirect on error + * and keep the user on the same page. + */ +export function getRedirectUrl(authUrl: string) { + const { custom, teamSubdomain, host } = parseDomain(window.location.origin); + const url = new URL(env.URL); + url.pathname = authUrl; + + if (custom || teamSubdomain) { + url.searchParams.set("host", host); + } + if (Desktop.isElectron()) { + url.searchParams.set("client", Client.Desktop); + } + + return url.toString(); +} diff --git a/app/scenes/Login/index.tsx b/app/scenes/Login/index.tsx index 57f82919c..9a9650b48 100644 --- a/app/scenes/Login/index.tsx +++ b/app/scenes/Login/index.tsx @@ -33,6 +33,7 @@ import { detectLanguage } from "~/utils/language"; import AuthenticationProvider from "./components/AuthenticationProvider"; import BackButton from "./components/BackButton"; import Notices from "./components/Notices"; +import { getRedirectUrl } from "./getRedirectUrl"; type Props = { children?: (config?: Config) => React.ReactNode; @@ -227,6 +228,12 @@ function Login({ children }: Props) { ); } + // If there is only one provider and it's OIDC, redirect immediately. + if (config.providers.length === 1 && config.providers[0].id === "oidc") { + window.location.href = getRedirectUrl(config.providers[0].authUrl); + return null; + } + return (