From cf7560926b21bfdacb59bb22dc7d34da7926f01b Mon Sep 17 00:00:00 2001 From: Sara Date: Thu, 11 Jun 2026 18:16:56 +0800 Subject: [PATCH] fix agent settings permissions --- frontend/src/pages/OpenClawSettings.tsx | 28 ++++++++++------- .../pages/agent-detail/AgentDetailPage.tsx | 18 ++++++----- .../pages/agent-detail/tabs/ApprovalsTab.tsx | 19 +++++++----- .../pages/agent-detail/tabs/SettingsTab.tsx | 31 ++++++++++++------- .../src/pages/agent-detail/tabs/SkillsTab.tsx | 9 ++++-- 5 files changed, 64 insertions(+), 41 deletions(-) diff --git a/frontend/src/pages/OpenClawSettings.tsx b/frontend/src/pages/OpenClawSettings.tsx index 9c4a90328..2988297d8 100644 --- a/frontend/src/pages/OpenClawSettings.tsx +++ b/frontend/src/pages/OpenClawSettings.tsx @@ -15,9 +15,10 @@ function fetchAuth(url: string, options?: RequestInit): Promise { interface OpenClawSettingsProps { agent: any; agentId: string; + canManage: boolean; } -export default function OpenClawSettings({ agent, agentId }: OpenClawSettingsProps) { +export default function OpenClawSettings({ agent, agentId, canManage }: OpenClawSettingsProps) { const { t, i18n } = useTranslation(); const queryClient = useQueryClient(); const navigate = useNavigate(); @@ -34,6 +35,7 @@ export default function OpenClawSettings({ agent, agentId }: OpenClawSettingsPro const hasKey = agent?.has_api_key || false; const handleRegenerate = async (autoCopy = false) => { + if (!canManage) return; setRegenerating(true); try { const result = await fetchAuth<{ api_key: string }>(`/agents/${agentId}/api-key`, { method: 'POST' }); @@ -56,6 +58,7 @@ export default function OpenClawSettings({ agent, agentId }: OpenClawSettingsPro }; const handleDelete = async () => { + if (!canManage) return; setDeleting(true); try { await agentApi.delete(agentId); @@ -75,6 +78,7 @@ export default function OpenClawSettings({ agent, agentId }: OpenClawSettingsPro }); const handleScopeChange = async (newScope: string) => { + if (!canManage || !isOwner) return; try { await fetchAuth(`/agents/${agentId}/permissions`, { method: 'PUT', @@ -89,6 +93,7 @@ export default function OpenClawSettings({ agent, agentId }: OpenClawSettingsPro }; const handleAccessLevelChange = async (newLevel: string) => { + if (!canManage || !isOwner) return; try { await fetchAuth(`/agents/${agentId}/permissions`, { method: 'PUT', @@ -103,6 +108,7 @@ export default function OpenClawSettings({ agent, agentId }: OpenClawSettingsPro }; const isOwner = permData?.is_owner ?? false; + const canEditPermissions = canManage && isOwner; const currentScope = permData?.scope_type === 'user' ? 'private' : (permData?.scope_type || 'company'); const currentAccessLevel = permData?.access_level || 'use'; @@ -146,13 +152,13 @@ export default function OpenClawSettings({ agent, agentId }: OpenClawSettingsPro copiedLabel="Copied" style={{ padding: '4px 12px', fontSize: '12px', whiteSpace: 'nowrap', minWidth: '70px', height: 'fit-content' }} /> - + } ); } @@ -169,7 +175,7 @@ export default function OpenClawSettings({ agent, agentId }: OpenClawSettingsPro ? (isChinese ? '旧版密钥(已加密隐藏),请重新生成以查看明文' : 'Legacy key (encrypted), please regenerate to view') : (isChinese ? '未生成' : 'Not generated')} - + } ); })()} @@ -214,7 +220,7 @@ export default function OpenClawSettings({ agent, agentId }: OpenClawSettingsPro - ) : agent.status === 'running' ? ( + )} + {canManage && agent.status === 'running' && ( - ) : null} + )} )} @@ -4900,7 +4901,7 @@ export default function AgentDetailPage() { {activeTab !== 'chat' &&
{AGENT_DETAIL_TABS.filter(tab => { if (['aware', 'workspace', 'chat'].includes(tab)) return false; - // 'use' access: hide settings and approvals tabs + // 'use' access keeps the existing tab bar unchanged; settings remains available via its own entry. if ((agent as any)?.access_level === 'use') { if (tab === 'settings' || tab === 'approvals') return false; } @@ -5109,7 +5110,7 @@ export default function AgentDetailPage() { {/* Quick Actions */}
- + {canManage && }
); @@ -5353,9 +5354,10 @@ export default function AgentDetailPage() { {trig.is_enabled ? t('agent.aware.inProgress') : t('agent.aware.completed')}
- {!trig.is_system &&
)} -
+ {canManage &&
-
+
} ))}
diff --git a/frontend/src/pages/agent-detail/tabs/SettingsTab.tsx b/frontend/src/pages/agent-detail/tabs/SettingsTab.tsx index eef9d490f..6b4c6f327 100644 --- a/frontend/src/pages/agent-detail/tabs/SettingsTab.tsx +++ b/frontend/src/pages/agent-detail/tabs/SettingsTab.tsx @@ -68,30 +68,35 @@ export default function SettingsTab(props: Props) { onDeleteAgent, } = props; const { t, i18n } = useTranslation(); + const readOnly = !canManage; + const canSave = canManage && hasChanges && !settingsSaving; if ((agent as any)?.agent_type === 'openclaw') { - return ; + return ; } return ( -
+
+
{settingsSaved && {t('agent.settings.saved', 'Saved')}} {settingsError && {settingsError}} - + }
@@ -237,7 +242,7 @@ export default function SettingsTab(props: Props) {

{isChinese ? '当用户在网页端发起新对话时,Agent 会自动发送的欢迎语。支持 Markdown 语法。留空则不发送。' : 'Greeting message sent automatically when a user starts a new web conversation. Supports Markdown. Leave empty to disable.'}

-