fix redirect issue in firefox and safari

This commit is contained in:
miloschwartz
2025-10-05 14:59:34 -07:00
parent 165f4023d0
commit 9649d9a46b
4 changed files with 87 additions and 42 deletions

View File

@@ -1724,5 +1724,6 @@
"authPageUpdated": "Auth page updated successfully", "authPageUpdated": "Auth page updated successfully",
"healthCheckNotAvailable": "Local", "healthCheckNotAvailable": "Local",
"rewritePath": "Rewrite Path", "rewritePath": "Rewrite Path",
"rewritePathDescription": "Optionally rewrite the path before forwarding to the target." "rewritePathDescription": "Optionally rewrite the path before forwarding to the target.",
"continueToApplication": "Continue to application"
} }

View File

@@ -57,9 +57,12 @@ function parseSetCookieString(
} }
if (!options.domain) { if (!options.domain) {
const d = host ? new URL(env.app.dashboardUrl).hostname : undefined; const d = host
? host.split(":")[0] // strip port if present
: new URL(env.app.dashboardUrl).hostname;
if (d) { if (d) {
options.domain = d; options.domain = d;
console.log("Setting cookie domain to:", d);
} }
} }
@@ -91,7 +94,8 @@ async function makeApiRequest<T>(
res = await fetch(url, { res = await fetch(url, {
method, method,
headers, headers,
body: body ? JSON.stringify(body) : undefined body: body ? JSON.stringify(body) : undefined,
cache: "no-store"
}); });
} catch (fetchError) { } catch (fetchError) {
console.error("API request failed:", fetchError); console.error("API request failed:", fetchError);

View File

@@ -69,6 +69,8 @@ export default async function OrgAuthPage(props: {
const t = await getTranslations(); const t = await getTranslations();
const expectedHost = env.app.dashboardUrl.split("//")[1]; const expectedHost = env.app.dashboardUrl.split("//")[1];
let redirectToUrl: string | undefined;
let loginPage: LoadLoginPageResponse | undefined; let loginPage: LoadLoginPageResponse | undefined;
if (host !== expectedHost) { if (host !== expectedHost) {
try { try {
@@ -110,7 +112,6 @@ export default async function OrgAuthPage(props: {
if (res && res.status === 200) { if (res && res.status === 200) {
const newToken = res.data.data.token; const newToken = res.data.data.token;
redirectToken = newToken; redirectToken = newToken;
} }
} catch (e) { } catch (e) {
@@ -120,9 +121,8 @@ export default async function OrgAuthPage(props: {
} }
if (redirectToken) { if (redirectToken) {
redirect( redirectToUrl = `${env.app.dashboardUrl}/auth/org?token=${redirectToken}`;
`${env.app.dashboardUrl}/auth/org?token=${redirectToken}` redirect(redirectToUrl);
);
} }
} }
} else { } else {

View File

@@ -13,13 +13,21 @@
"use client"; "use client";
import { useState } from "react"; import { useEffect, useState } from "react";
import { Button } from "@app/components/ui/button"; import { Button } from "@app/components/ui/button";
import { Alert, AlertDescription } from "@app/components/ui/alert"; import { Alert, AlertDescription } from "@app/components/ui/alert";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
import Image from "next/image"; import Image from "next/image";
import { generateOidcUrlProxy, type GenerateOidcUrlResponse } from "@app/actions/server"; import {
import { redirect as redirectTo } from "next/navigation"; generateOidcUrlProxy,
type GenerateOidcUrlResponse
} from "@app/actions/server";
import {
redirect as redirectTo,
useParams,
useSearchParams
} from "next/navigation";
import { useRouter } from "next/navigation";
export type LoginFormIDP = { export type LoginFormIDP = {
idpId: number; idpId: number;
@@ -42,6 +50,20 @@ export default function IdpLoginButtons({
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const t = useTranslations(); const t = useTranslations();
const params = useSearchParams();
const router = useRouter();
function goToApp() {
const url = window.location.href.split("?")[0];
router.push(url);
}
useEffect(() => {
if (params.get("gotoapp")) {
goToApp();
}
}, []);
async function loginWithIdp(idpId: number) { async function loginWithIdp(idpId: number) {
setLoading(true); setLoading(true);
setError(null); setError(null);
@@ -50,7 +72,7 @@ export default function IdpLoginButtons({
try { try {
const response = await generateOidcUrlProxy( const response = await generateOidcUrlProxy(
idpId, idpId,
redirect || "/", redirect || "/auth/org?gotoapp=app",
orgId orgId
); );
@@ -69,7 +91,8 @@ export default function IdpLoginButtons({
console.error(e); console.error(e);
setError( setError(
t("loginError", { t("loginError", {
defaultValue: "An unexpected error occurred. Please try again." defaultValue:
"An unexpected error occurred. Please try again."
}) })
); );
setLoading(false); setLoading(false);
@@ -93,42 +116,59 @@ export default function IdpLoginButtons({
)} )}
<div className="space-y-2"> <div className="space-y-2">
{idps.map((idp) => { {params.get("gotoapp") ? (
const effectiveType = idp.variant || idp.name.toLowerCase(); <>
return (
<Button <Button
key={idp.idpId}
type="button" type="button"
variant="outline" className="w-full"
className="w-full inline-flex items-center space-x-2"
onClick={() => { onClick={() => {
loginWithIdp(idp.idpId); goToApp();
}} }}
disabled={loading}
> >
{effectiveType === "google" && ( {t("continueToApplication")}
<Image
src="/idp/google.png"
alt="Google"
width={16}
height={16}
className="rounded"
/>
)}
{effectiveType === "azure" && (
<Image
src="/idp/azure.png"
alt="Azure"
width={16}
height={16}
className="rounded"
/>
)}
<span>{idp.name}</span>
</Button> </Button>
); </>
})} ) : (
<>
{idps.map((idp) => {
const effectiveType =
idp.variant || idp.name.toLowerCase();
return (
<Button
key={idp.idpId}
type="button"
variant="outline"
className="w-full inline-flex items-center space-x-2"
onClick={() => {
loginWithIdp(idp.idpId);
}}
disabled={loading}
>
{effectiveType === "google" && (
<Image
src="/idp/google.png"
alt="Google"
width={16}
height={16}
className="rounded"
/>
)}
{effectiveType === "azure" && (
<Image
src="/idp/azure.png"
alt="Azure"
width={16}
height={16}
className="rounded"
/>
)}
<span>{idp.name}</span>
</Button>
);
})}
</>
)}
</div> </div>
</div> </div>
); );