From 63d3123fa7c54240415aef9721a20d3a06359f41 Mon Sep 17 00:00:00 2001 From: msukkari Date: Thu, 24 Jul 2025 10:37:15 -0700 Subject: [PATCH] hide member page if not owner --- .../src/app/[domain]/settings/access/page.tsx | 19 +++++++++ .../web/src/app/[domain]/settings/layout.tsx | 6 +-- .../app/[domain]/settings/members/page.tsx | 5 +++ .../web/src/app/login/components/demoCard.tsx | 39 ------------------- .../src/app/login/components/loginForm.tsx | 6 --- 5 files changed, 27 insertions(+), 48 deletions(-) delete mode 100644 packages/web/src/app/login/components/demoCard.tsx diff --git a/packages/web/src/app/[domain]/settings/access/page.tsx b/packages/web/src/app/[domain]/settings/access/page.tsx index cbce7b50..402868b3 100644 --- a/packages/web/src/app/[domain]/settings/access/page.tsx +++ b/packages/web/src/app/[domain]/settings/access/page.tsx @@ -1,5 +1,10 @@ import { getOrgFromDomain } from "@/data/org"; import { OrganizationAccessSettings } from "@/app/components/organizationAccessSettings"; +import { isServiceError } from "@/lib/utils"; +import { ServiceErrorException } from "@/lib/serviceError"; +import { getMe } from "@/actions"; +import { OrgRole } from "@sourcebot/db"; +import { redirect } from "next/navigation"; interface AccessPageProps { params: { @@ -13,6 +18,20 @@ export default async function AccessPage({ params: { domain } }: AccessPageProps throw new Error("Organization not found"); } + const me = await getMe(); + if (isServiceError(me)) { + throw new ServiceErrorException(me); + } + + const userRoleInOrg = me.memberships.find((membership) => membership.id === org.id)?.role; + if (!userRoleInOrg) { + throw new Error("User role not found"); + } + + if (userRoleInOrg !== OrgRole.OWNER) { + redirect(`/${domain}/settings`); + } + return (
diff --git a/packages/web/src/app/[domain]/settings/layout.tsx b/packages/web/src/app/[domain]/settings/layout.tsx index 014bb467..cc8128a7 100644 --- a/packages/web/src/app/[domain]/settings/layout.tsx +++ b/packages/web/src/app/[domain]/settings/layout.tsx @@ -70,11 +70,11 @@ export default async function SettingsLayout({ href: `/${domain}/settings/access`, } ] : []), - { + ...(userRoleInOrg === OrgRole.OWNER ? [{ title: (
Members - {userRoleInOrg === OrgRole.OWNER && numJoinRequests !== undefined && numJoinRequests > 0 && ( + {numJoinRequests !== undefined && numJoinRequests > 0 && ( {numJoinRequests} @@ -82,7 +82,7 @@ export default async function SettingsLayout({
), href: `/${domain}/settings/members`, - }, + }] : []), { title: "Secrets", href: `/${domain}/settings/secrets`, diff --git a/packages/web/src/app/[domain]/settings/members/page.tsx b/packages/web/src/app/[domain]/settings/members/page.tsx index 2c23f3f7..a7696aa8 100644 --- a/packages/web/src/app/[domain]/settings/members/page.tsx +++ b/packages/web/src/app/[domain]/settings/members/page.tsx @@ -12,6 +12,7 @@ import { ServiceErrorException } from "@/lib/serviceError"; import { getSeats, SOURCEBOT_UNLIMITED_SEATS } from "@sourcebot/shared"; import { RequestsList } from "./components/requestsList"; import { OrgRole } from "@prisma/client"; +import { redirect } from "next/navigation"; interface MembersSettingsPageProps { params: { @@ -38,6 +39,10 @@ export default async function MembersSettingsPage({ params: { domain }, searchPa throw new Error("User role not found"); } + if (userRoleInOrg !== OrgRole.OWNER) { + redirect(`/${domain}/settings`); + } + const members = await getOrgMembers(domain); if (isServiceError(members)) { throw new ServiceErrorException(members); diff --git a/packages/web/src/app/login/components/demoCard.tsx b/packages/web/src/app/login/components/demoCard.tsx deleted file mode 100644 index b9bfe93a..00000000 --- a/packages/web/src/app/login/components/demoCard.tsx +++ /dev/null @@ -1,39 +0,0 @@ -"use client" - -import { ExternalLink } from "lucide-react" -import Link from "next/link" - -import { Button } from "@/components/ui/button" -import { Card, CardContent } from "@/components/ui/card" -import useCaptureEvent from "@/hooks/useCaptureEvent" - -export default function DemoCard() { - const captureEvent = useCaptureEvent(); - - return ( - - -
-
-
-

New to Sourcebot?

-

Try our public demo before creating an account

-
- - -
-
-
-
- ) -} diff --git a/packages/web/src/app/login/components/loginForm.tsx b/packages/web/src/app/login/components/loginForm.tsx index ff0e555c..05daabac 100644 --- a/packages/web/src/app/login/components/loginForm.tsx +++ b/packages/web/src/app/login/components/loginForm.tsx @@ -5,7 +5,6 @@ import { Card } from "@/components/ui/card"; import { SourcebotLogo } from "@/app/components/sourcebotLogo"; import { AuthMethodSelector } from "@/app/components/authMethodSelector"; import useCaptureEvent from "@/hooks/useCaptureEvent"; -import DemoCard from "@/app/login/components/demoCard"; import Link from "next/link"; import { env } from "@/env.mjs"; import type { AuthProvider } from "@/lib/authProviders"; @@ -72,11 +71,6 @@ export const LoginForm = ({ callbackUrl, error, providers, context }: LoginFormP {context === "login" ? "Sign in to your account" : "Create a new account"}
- {env.NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT !== undefined && ( -
- -
- )} {error && (