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}