From 2e8af04531c4baf5c7694c3543d823a8478188e6 Mon Sep 17 00:00:00 2001 From: GatewayJ <835269233@qq.com> Date: Sat, 28 Feb 2026 11:40:10 +0800 Subject: [PATCH] fix(ui): show Change Password only for users with consoleAdmin Align with RustFS backend: only users with consoleAdmin policy can change password (see rustfs/rustfs#1923). Add canChangePassword to permissions (isAdmin or has consoleAdmin scope) and show the menu item only when true, so non-admin users no longer see the option and get 403 on submit. Made-with: Cursor --- components/user/dropdown.tsx | 4 ++-- hooks/use-permissions.tsx | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/components/user/dropdown.tsx b/components/user/dropdown.tsx index 95ef9517..691c7b51 100644 --- a/components/user/dropdown.tsx +++ b/components/user/dropdown.tsx @@ -18,7 +18,7 @@ export function UserDropdown() { const { t } = useTranslation() const router = useRouter() const { logout, isAdmin, setIsAdmin } = useAuth() - const { userInfo } = usePermissions() + const { userInfo, canChangePassword } = usePermissions() const { isAdminUser } = useUsers() const { state } = useSidebar() const isCollapsed = state === "collapsed" @@ -68,7 +68,7 @@ export function UserDropdown() { {(userInfo as { account_name?: string })?.account_name ?? (isAdmin ? "rustfsAdmin" : "")} - {!isAdmin && ( + {canChangePassword && ( {t("Change Password")} diff --git a/hooks/use-permissions.tsx b/hooks/use-permissions.tsx index 499bde84..a32f0533 100644 --- a/hooks/use-permissions.tsx +++ b/hooks/use-permissions.tsx @@ -2,7 +2,7 @@ import { createContext, useContext, useState, useCallback, useEffect, useMemo } from "react" import { hasConsoleScopes, type ConsolePolicy } from "@/lib/console-policy-parser" -import { PAGE_PERMISSIONS } from "@/lib/console-permissions" +import { CONSOLE_SCOPES, PAGE_PERMISSIONS } from "@/lib/console-permissions" import { useAuth } from "@/contexts/auth-context" import { useApiOptional } from "@/contexts/api-context" @@ -15,6 +15,8 @@ interface PermissionsContextValue { hasPermission: (action: string | string[], matchAll?: boolean) => boolean canAccessPath: (path: string) => boolean isAdmin: boolean + /** True when user has consoleAdmin (or is admin). Only these users can change password per RustFS backend. */ + canChangePassword: boolean } const PermissionsContext = createContext(null) @@ -92,6 +94,8 @@ export function PermissionsProvider({ children }: { children: React.ReactNode }) } }, [api, isAuthenticated, isAdmin, hasFetchedPolicy, isLoading, fetchUserPolicy]) + const canChangePassword = isAdmin || hasPermission(CONSOLE_SCOPES.CONSOLE_ADMIN) + const value = useMemo( () => ({ userPolicy, @@ -102,8 +106,9 @@ export function PermissionsProvider({ children }: { children: React.ReactNode }) hasPermission, canAccessPath, isAdmin, + canChangePassword, }), - [userPolicy, userInfo, isLoading, hasFetchedPolicy, fetchUserPolicy, hasPermission, canAccessPath, isAdmin], + [userPolicy, userInfo, isLoading, hasFetchedPolicy, fetchUserPolicy, hasPermission, canAccessPath, isAdmin, canChangePassword], ) return {children}