fix(ui): hide billing when Cloud billing is disabled (#12047)

This commit is contained in:
Alejandro Bailo
2026-07-20 10:04:48 +02:00
committed by GitHub
parent ce9d46065a
commit 4b72cc8dd4
5 changed files with 33 additions and 7 deletions
@@ -0,0 +1 @@
Billing navigation is hidden when Cloud billing is disabled, including Enterprise deployments
@@ -24,10 +24,15 @@ interface AppSidebarContentProps {
export function AppSidebarContent({ onSelect }: AppSidebarContentProps) {
const pathname = usePathname();
const { permissions } = useAuth();
const { apiDocsUrl } = useRuntimeConfig();
const { apiDocsUrl, cloudBillingEnabled } = useRuntimeConfig();
const mode = useAppSidebarMode((state) => state.mode);
const isCloudEnvironment = isCloud();
const sections = getNavigationConfig({ pathname, apiDocsUrl, permissions });
const sections = getNavigationConfig({
pathname,
apiDocsUrl,
cloudBillingEnabled,
permissions,
});
const showChat = isCloudEnvironment && mode === APP_SIDEBAR_MODE.CHAT;
return (
@@ -157,6 +157,7 @@ describe("getNavigationConfig", () => {
const billing = getNavigationConfig({
pathname: "/billing",
apiDocsUrl: null,
cloudBillingEnabled: true,
permissions,
})
.flatMap((section) => section.items)
@@ -183,17 +184,28 @@ describe("getNavigationConfig", () => {
const cloudItems = getNavigationConfig({
pathname: "/",
apiDocsUrl: null,
cloudBillingEnabled: true,
permissions,
}).flatMap((section) => section.items);
const enterpriseItems = getNavigationConfig({
pathname: "/",
apiDocsUrl: null,
cloudBillingEnabled: false,
permissions: { ...permissions, manage_billing: true },
}).flatMap((section) => section.items);
vi.stubEnv("NEXT_PUBLIC_IS_CLOUD_ENV", "false");
const localItems = getNavigationConfig({
pathname: "/",
apiDocsUrl: null,
cloudBillingEnabled: true,
permissions: { ...permissions, manage_billing: true },
}).flatMap((section) => section.items);
// Then
expect(cloudItems.find((item) => item.label === "Billing")).toBeUndefined();
expect(
enterpriseItems.find((item) => item.label === "Billing"),
).toBeUndefined();
expect(localItems.find((item) => item.label === "Billing")).toBeUndefined();
});
@@ -31,6 +31,7 @@ import {
interface NavigationConfigOptions {
pathname: string;
apiDocsUrl?: string | null;
cloudBillingEnabled?: boolean;
permissions?: RolePermissionAttributes;
}
@@ -106,6 +107,7 @@ export function filterNavigationByPermissions(
export function getNavigationConfig({
pathname,
apiDocsUrl = null,
cloudBillingEnabled = false,
permissions,
}: NavigationConfigOptions): NavigationSection[] {
const isCloudEnvironment = isCloud();
@@ -265,7 +267,7 @@ export function getNavigationConfig({
},
],
},
...(isCloudEnvironment
...(isCloudEnvironment && cloudBillingEnabled
? [
{
kind: NAVIGATION_ITEM_KIND.LINK,
+10 -4
View File
@@ -2,6 +2,7 @@ import { NextResponse } from "next/server";
import type { NextAuthRequest } from "next-auth";
import { auth } from "@/auth.config";
import { readEnv } from "@/lib/runtime-env";
const publicRoutes = [
"/sign-in",
@@ -23,6 +24,8 @@ export default auth((req: NextAuthRequest) => {
const user = req.auth?.user;
const sessionError = req.auth?.error;
const cloudBillingEnabled =
(readEnv("CLOUD_BILLING_ENABLED") ?? "false") !== "false";
// If there's a session error (e.g., RefreshAccessTokenError), redirect to login with error info
if (sessionError && !isPublicRoute(pathname)) {
@@ -38,13 +41,16 @@ export default auth((req: NextAuthRequest) => {
return NextResponse.redirect(signInUrl);
}
if (
pathname.startsWith("/billing") &&
(!cloudBillingEnabled || user?.permissions?.manage_billing !== true)
) {
return NextResponse.redirect(new URL("/profile", req.url));
}
if (user?.permissions) {
const permissions = user.permissions;
if (pathname.startsWith("/billing") && !permissions.manage_billing) {
return NextResponse.redirect(new URL("/profile", req.url));
}
if (
pathname.startsWith("/integrations") &&
!permissions.manage_integrations