diff --git a/server/routers/badger/verifySession.ts b/server/routers/badger/verifySession.ts index ee69ce163..b95b5925c 100644 --- a/server/routers/badger/verifySession.ts +++ b/server/routers/badger/verifySession.ts @@ -337,10 +337,16 @@ export async function verifyResourceSession( // Only offer a browser redirect to clients that can actually follow one and log in // (an interactive browser). Non-browser clients (curl, scripts, bots, etc.) just get // an unauthorized response from Badger instead of a login redirect URL. + // Inference browsers go to the dashboard keys page (not back to the inference host) + // so a valid session cannot create a redirect loop. const redirectPath = clientIsBrowser - ? `/auth/resource/${encodeURIComponent( - resource.resourceGuid - )}?redirect=${encodeURIComponent(originalRequestURL)}` + ? mode === "inference" + ? `/${resource.orgId}/resource/${encodeURIComponent( + resource.resourceGuid + )}/keys` + : `/auth/resource/${encodeURIComponent( + resource.resourceGuid + )}?redirect=${encodeURIComponent(originalRequestURL)}` : undefined; // Virtual API keys for public inference resources (provider-style auth headers). diff --git a/server/routers/resource/getResourceAuthInfo.ts b/server/routers/resource/getResourceAuthInfo.ts index f1328833d..667870959 100644 --- a/server/routers/resource/getResourceAuthInfo.ts +++ b/server/routers/resource/getResourceAuthInfo.ts @@ -42,6 +42,7 @@ export type GetResourceAuthInfoResponse = { skipToIdpId: number | null; orgId: string; postAuthPath: string | null; + mode: string; }; export async function getResourceAuthInfo( @@ -227,7 +228,8 @@ export async function getResourceAuthInfo( whitelist: effectivePolicy?.emailWhitelistEnabled ?? false, skipToIdpId: effectivePolicy?.idpId ?? resource.skipToIdpId, orgId: resource.orgId, - postAuthPath: resource.postAuthPath ?? null + postAuthPath: resource.postAuthPath ?? null, + mode: resource.mode }, success: true, error: false, diff --git a/src/app/[orgId]/resource/[resourceGuid]/keys/page.tsx b/src/app/[orgId]/resource/[resourceGuid]/keys/page.tsx index 29e11eb92..98d4b6582 100644 --- a/src/app/[orgId]/resource/[resourceGuid]/keys/page.tsx +++ b/src/app/[orgId]/resource/[resourceGuid]/keys/page.tsx @@ -41,7 +41,9 @@ export default async function ResourceKeysPage(props: ResourceKeysPageProps) { const user = await getUser(); if (!user) { - redirect("/"); + redirect( + `/auth/login?redirect=/${orgId}/resource/${resourceGuid}/keys` + ); } const cookieHeader = await authCookieHeader(); diff --git a/src/app/auth/resource/[resourceGuid]/page.tsx b/src/app/auth/resource/[resourceGuid]/page.tsx index dafc13f8f..4376bebc2 100644 --- a/src/app/auth/resource/[resourceGuid]/page.tsx +++ b/src/app/auth/resource/[resourceGuid]/page.tsx @@ -71,6 +71,9 @@ export default async function ResourceAuthPage(props: { ); } + const isInference = authInfo.mode === "inference"; + const keysPath = `/${authInfo.orgId}/resource/${authInfo.resourceGuid}/keys`; + const hasLoginPageDomain = await isOrgSubscribed( authInfo.orgId, tierMatrix.loginPageDomain @@ -159,10 +162,18 @@ export default async function ResourceAuthPage(props: { if (user && !user.emailVerified && env.flags.emailVerificationRequired) { redirect( - `/auth/verify-email?redirect=/auth/resource/${authInfo.resourceGuid}` + `/auth/verify-email?redirect=${encodeURIComponent( + isInference + ? keysPath + : `/auth/resource/${authInfo.resourceGuid}` + )}` ); } + if (isInference && !user) { + redirect(`/auth/login?redirect=${encodeURIComponent(keysPath)}`); + } + const cookie = await authCookieHeader(); // Check org policy compliance before proceeding @@ -181,7 +192,9 @@ export default async function ResourceAuthPage(props: { // If user is not compliant with org policies, show policy requirements if (orgPolicyCheck && !orgPolicyCheck.allowed && orgPolicyCheck.policies) { - const resourceAuthPageUrl = `/auth/resource/${authInfo.resourceGuid}${redirectUrl !== authInfo.url ? `?redirect=${encodeURIComponent(redirectUrl)}` : ""}`; + const resourceAuthPageUrl = isInference + ? keysPath + : `/auth/resource/${authInfo.resourceGuid}${redirectUrl !== authInfo.url ? `?redirect=${encodeURIComponent(redirectUrl)}` : ""}`; return (