diff --git a/server/routers/badger/verifySession.ts b/server/routers/badger/verifySession.ts index 459219c5..c369aef4 100644 --- a/server/routers/badger/verifySession.ts +++ b/server/routers/badger/verifySession.ts @@ -101,7 +101,8 @@ export async function verifyResourceSession( return allowed(res); } - const redirectUrl = `${config.getRawConfig().app.dashboard_url}/auth/resource/${encodeURIComponent(resource.resourceId)}?redirect=${encodeURIComponent(originalRequestURL)}`; + // const redirectUrl = `${config.getRawConfig().app.dashboard_url}/auth/resource/${encodeURIComponent(resource.resourceId)}?redirect=${encodeURIComponent(originalRequestURL)}`; + const redirectUrl = `${config.getRawConfig().app.dashboard_url}/auth/resource/${encodeURIComponent(resource.resourceId)}`; if (!sessions) { return notAllowed(res); diff --git a/src/app/[orgId]/layout.tsx b/src/app/[orgId]/layout.tsx index b8b5c6a9..fa41beb2 100644 --- a/src/app/[orgId]/layout.tsx +++ b/src/app/[orgId]/layout.tsx @@ -25,7 +25,7 @@ export default async function OrgLayout(props: { const user = await getUser(); if (!user) { - redirect(`/?redirect=/${orgId}`); + redirect(`/`); } try { diff --git a/src/app/[orgId]/settings/general/layout.tsx b/src/app/[orgId]/settings/general/layout.tsx index 5923118e..4b41b8c3 100644 --- a/src/app/[orgId]/settings/general/layout.tsx +++ b/src/app/[orgId]/settings/general/layout.tsx @@ -26,7 +26,7 @@ export default async function GeneralSettingsPage({ const user = await getUser(); if (!user) { - redirect(`/?redirect=/${orgId}/settings/general`); + redirect(`/`); } let orgUser = null; diff --git a/src/app/[orgId]/settings/layout.tsx b/src/app/[orgId]/settings/layout.tsx index 95a6cc00..b0b561a2 100644 --- a/src/app/[orgId]/settings/layout.tsx +++ b/src/app/[orgId]/settings/layout.tsx @@ -61,7 +61,7 @@ export default async function SettingsLayout(props: SettingsLayoutProps) { const user = await getUser(); if (!user) { - redirect(`/?redirect=/${params.orgId}/`); + redirect(`/`); } const cookie = await authCookieHeader(); diff --git a/src/app/auth/login/DashboardLoginForm.tsx b/src/app/auth/login/DashboardLoginForm.tsx index 088fc631..715a0fb9 100644 --- a/src/app/auth/login/DashboardLoginForm.tsx +++ b/src/app/auth/login/DashboardLoginForm.tsx @@ -13,6 +13,7 @@ import { useEnvContext } from "@app/hooks/useEnvContext"; import { useRouter } from "next/navigation"; import { useEffect } from "react"; import Image from "next/image"; +import { cleanRedirect } from "@app/lib/cleanRedirect"; type DashboardLoginFormProps = { redirect?: string; @@ -57,10 +58,9 @@ export default function DashboardLoginForm({ { - if (redirect && redirect.includes("http")) { - window.location.href = redirect; - } else if (redirect) { - router.push(redirect); + if (redirect) { + const safe = cleanRedirect(redirect); + router.push(safe); } else { router.push("/"); } diff --git a/src/app/auth/login/page.tsx b/src/app/auth/login/page.tsx index 87c27071..118cfcd0 100644 --- a/src/app/auth/login/page.tsx +++ b/src/app/auth/login/page.tsx @@ -5,6 +5,7 @@ import { cache } from "react"; import DashboardLoginForm from "./DashboardLoginForm"; import { Mail } from "lucide-react"; import { pullEnv } from "@app/lib/pullEnv"; +import { cleanRedirect } from "@app/lib/cleanRedirect"; export const dynamic = "force-dynamic"; @@ -25,6 +26,11 @@ export default async function Page(props: { redirect("/"); } + let redirectUrl: string | undefined = undefined; + if (searchParams.redirect) { + redirectUrl = cleanRedirect(searchParams.redirect as string); + } + return ( <> {isInvite && ( @@ -42,16 +48,16 @@ export default async function Page(props: { )} - + {(!signUpDisabled || isInvite) && (

Don't have an account?{" "} diff --git a/src/app/auth/reset-password/ResetPasswordForm.tsx b/src/app/auth/reset-password/ResetPasswordForm.tsx index a9232d4d..ae997818 100644 --- a/src/app/auth/reset-password/ResetPasswordForm.tsx +++ b/src/app/auth/reset-password/ResetPasswordForm.tsx @@ -43,6 +43,7 @@ import { createApiClient } from "@app/lib/api"; import { useEnvContext } from "@app/hooks/useEnvContext"; import { REGEXP_ONLY_DIGITS_AND_CHARS } from "input-otp"; import { passwordSchema } from "@server/auth/passwordSchema"; +import { cleanRedirect } from "@app/lib/cleanRedirect"; const requestSchema = z.object({ email: z.string().email() @@ -186,11 +187,9 @@ export default function ResetPasswordForm({ setSuccessMessage("Password reset successfully! Back to login..."); setTimeout(() => { - if (redirect && redirect.includes("http")) { - window.location.href = redirect; - } if (redirect) { - router.push(redirect); + const safe = cleanRedirect(redirect); + router.push(safe); } else { router.push("/login"); } diff --git a/src/app/auth/reset-password/page.tsx b/src/app/auth/reset-password/page.tsx index b5636c42..73654beb 100644 --- a/src/app/auth/reset-password/page.tsx +++ b/src/app/auth/reset-password/page.tsx @@ -3,6 +3,7 @@ import { redirect } from "next/navigation"; import { cache } from "react"; import ResetPasswordForm from "./ResetPasswordForm"; import Link from "next/link"; +import { cleanRedirect } from "@app/lib/cleanRedirect"; export const dynamic = "force-dynamic"; @@ -21,6 +22,11 @@ export default async function Page(props: { redirect("/"); } + let redirectUrl: string | undefined = undefined; + if (searchParams.redirect) { + redirectUrl = cleanRedirect(searchParams.redirect); + } + return ( <> diff --git a/src/app/auth/resource/[resourceId]/ResourceAuthPortal.tsx b/src/app/auth/resource/[resourceId]/ResourceAuthPortal.tsx index a25edf74..c23403a8 100644 --- a/src/app/auth/resource/[resourceId]/ResourceAuthPortal.tsx +++ b/src/app/auth/resource/[resourceId]/ResourceAuthPortal.tsx @@ -481,11 +481,7 @@ export default function ResourceAuthPortal(props: ResourceAuthPortalProps) { className={`${numMethods <= 1 ? "mt-0" : ""}`} > await handleSSOAuth() } diff --git a/src/app/auth/resource/[resourceId]/page.tsx b/src/app/auth/resource/[resourceId]/page.tsx index 886801c7..4258f688 100644 --- a/src/app/auth/resource/[resourceId]/page.tsx +++ b/src/app/auth/resource/[resourceId]/page.tsx @@ -55,7 +55,17 @@ export default async function ResourceAuthPage(props: { ); } - const redirectUrl = searchParams.redirect || authInfo.url; + let redirectUrl = authInfo.url; + // if (searchParams.redirect) { + // try { + // const serverResourceHost = new URL(authInfo.url).host; + // const redirectHost = new URL(searchParams.redirect).host; + // + // if (serverResourceHost === redirectHost) { + // redirectUrl = searchParams.redirect; + // } + // } catch (e) {} + // } const hasAuth = authInfo.password || diff --git a/src/app/auth/signup/SignupForm.tsx b/src/app/auth/signup/SignupForm.tsx index 9630d907..f839284e 100644 --- a/src/app/auth/signup/SignupForm.tsx +++ b/src/app/auth/signup/SignupForm.tsx @@ -30,6 +30,7 @@ import { formatAxiosError } from "@app/lib/api"; import { createApiClient } from "@app/lib/api"; import { useEnvContext } from "@app/hooks/useEnvContext"; import Image from "next/image"; +import { cleanRedirect } from "@app/lib/cleanRedirect"; type SignupFormProps = { redirect?: string; @@ -92,17 +93,17 @@ export default function SignupForm({ if (res.data?.data?.emailVerificationRequired) { if (redirect) { - router.push(`/auth/verify-email?redirect=${redirect}`); + const safe = cleanRedirect(redirect); + router.push(`/auth/verify-email?redirect=${safe}`); } else { router.push("/auth/verify-email"); } return; } - if (redirect && redirect.includes("http")) { - window.location.href = redirect; - } else if (redirect) { - router.push(redirect); + if (redirect) { + const safe = cleanRedirect(redirect); + router.push(safe); } else { router.push("/"); } diff --git a/src/app/auth/signup/page.tsx b/src/app/auth/signup/page.tsx index f53ff2c8..361cc0db 100644 --- a/src/app/auth/signup/page.tsx +++ b/src/app/auth/signup/page.tsx @@ -1,5 +1,6 @@ import SignupForm from "@app/app/auth/signup/SignupForm"; import { verifySession } from "@app/lib/auth/verifySession"; +import { cleanRedirect } from "@app/lib/cleanRedirect"; import { pullEnv } from "@app/lib/pullEnv"; import { Mail } from "lucide-react"; import Link from "next/link"; @@ -41,6 +42,11 @@ export default async function Page(props: { } } + let redirectUrl: string | undefined; + if (searchParams.redirect) { + redirectUrl = cleanRedirect(searchParams.redirect); + } + return ( <> {isInvite && ( @@ -59,7 +65,7 @@ export default async function Page(props: { )} @@ -68,9 +74,9 @@ export default async function Page(props: { Already have an account?{" "} diff --git a/src/app/auth/verify-email/VerifyEmailForm.tsx b/src/app/auth/verify-email/VerifyEmailForm.tsx index 7a6bc082..8a0ca89a 100644 --- a/src/app/auth/verify-email/VerifyEmailForm.tsx +++ b/src/app/auth/verify-email/VerifyEmailForm.tsx @@ -36,6 +36,7 @@ import { useRouter } from "next/navigation"; import { formatAxiosError } from "@app/lib/api";; import { createApiClient } from "@app/lib/api"; import { useEnvContext } from "@app/hooks/useEnvContext"; +import { cleanRedirect } from "@app/lib/cleanRedirect"; const FormSchema = z.object({ email: z.string().email({ message: "Invalid email address" }), @@ -91,11 +92,9 @@ export default function VerifyEmailForm({ "Email successfully verified! Redirecting you..." ); setTimeout(() => { - if (redirect && redirect.includes("http")) { - window.location.href = redirect; - } if (redirect) { - router.push(redirect); + const safe = cleanRedirect(redirect); + router.push(safe); } else { router.push("/"); } diff --git a/src/app/auth/verify-email/page.tsx b/src/app/auth/verify-email/page.tsx index 3452df69..033fa75d 100644 --- a/src/app/auth/verify-email/page.tsx +++ b/src/app/auth/verify-email/page.tsx @@ -1,5 +1,6 @@ import VerifyEmailForm from "@app/app/auth/verify-email/VerifyEmailForm"; import { verifySession } from "@app/lib/auth/verifySession"; +import { cleanRedirect } from "@app/lib/cleanRedirect"; import { pullEnv } from "@app/lib/pullEnv"; import { redirect } from "next/navigation"; import { cache } from "react"; @@ -27,11 +28,16 @@ export default async function Page(props: { redirect("/"); } + let redirectUrl: string | undefined; + if (searchParams.redirect) { + redirectUrl = cleanRedirect(searchParams.redirect as string); + } + return ( <> ); diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 16ce9963..b4abbad3 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -6,6 +6,8 @@ import { ThemeProvider } from "@app/providers/ThemeProvider"; import EnvProvider from "@app/providers/EnvProvider"; import { Separator } from "@app/components/ui/separator"; import { pullEnv } from "@app/lib/pullEnv"; +import { BookOpenText } from "lucide-react"; +import Image from "next/image"; export const metadata: Metadata = { title: `Dashboard - Pangolin`, @@ -38,10 +40,10 @@ export default async function RootLayout({

{children}
{/* Footer */} -