fix: Unable to link secondary auth provider on custom domain (#12356)

* fix: Unable to link secondary auth provider on custom domain

* doc
This commit is contained in:
Tom Moor
2026-05-14 21:02:12 -04:00
committed by GitHub
parent 246aa83071
commit 061ba46255
5 changed files with 34 additions and 29 deletions
+2 -1
View File
@@ -40,8 +40,9 @@ import { BackButton } from "./components/BackButton";
import { Background } from "./components/Background";
import { Centered } from "./components/Centered";
import { Notices } from "./components/Notices";
import { getRedirectUrl, navigateToSubdomain } from "./urls";
import { navigateToSubdomain } from "./urls";
import lazyWithRetry from "~/utils/lazyWithRetry";
import { getRedirectUrl } from "~/utils/urls";
const WorkspaceSetup = lazyWithRetry(
() => import("./components/WorkspaceSetup")
@@ -11,7 +11,7 @@ import PluginIcon from "~/components/PluginIcon";
import Tooltip from "~/components/Tooltip";
import { client } from "~/utils/ApiClient";
import Desktop from "~/utils/Desktop";
import { getRedirectUrl } from "../urls";
import { getRedirectUrl } from "~/utils/urls";
import { CSRF } from "@shared/constants";
import { getCookie } from "tiny-cookie";
-26
View File
@@ -1,6 +1,3 @@
import { Client } from "@shared/types";
import { parseDomain } from "@shared/utils/domains";
import env from "~/env";
import Desktop from "~/utils/Desktop";
function validateAndEncodeSubdomain(subdomain: string): string {
@@ -12,29 +9,6 @@ function validateAndEncodeSubdomain(subdomain: string): string {
return `https://${encodedSubdomain}.getoutline.com`;
}
/**
* 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.
*
* @param authUrl The URL to redirect to after authentication
*/
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();
}
/**
* Redirect to a subdomain, adding it to the custom hosts list on desktop first.
*
+2 -1
View File
@@ -19,6 +19,7 @@ import useRequest from "~/hooks/useRequest";
import useStores from "~/hooks/useStores";
import SettingRow from "./components/SettingRow";
import { setPostLoginPath } from "~/hooks/useLastVisitedPath";
import { getRedirectUrl } from "~/utils/urls";
import { settingsPath } from "~/utils/routeHelpers";
import DomainManagement from "./components/DomainManagement";
import Button from "~/components/Button";
@@ -97,7 +98,7 @@ function Authentication() {
const handleConnectProvider = React.useCallback((name: string) => {
setPostLoginPath(settingsPath("authentication"));
window.location.href = `/auth/${name}?host=${window.location.host}`;
window.location.href = getRedirectUrl(`/auth/${name}`);
}, []);
const handleToggleGroupSync = React.useCallback(
+29
View File
@@ -1,3 +1,32 @@
import { Client } from "@shared/types";
import { parseDomain } from "@shared/utils/domains";
import env from "~/env";
import Desktop from "~/utils/Desktop";
/**
* Builds an absolute auth redirect URL against the apex (env.URL). When the
* user is on a custom domain or team subdomain the auth flow must start on the
* apex so that the OAuth state cookie can be set and later read by the
* callback. The originating host is forwarded as a query param so the server
* can return the user to the same page on error or after sign-in.
*
* @param authUrl The auth endpoint path to redirect to (e.g. "/auth/google").
*/
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();
}
export function isHash(href: string) {
if (href[0] === "#") {
return true;