diff --git a/bff/app.py b/bff/app.py index 38975ce..6172869 100644 --- a/bff/app.py +++ b/bff/app.py @@ -237,6 +237,10 @@ async def update_member(slug: str, request: Request, user: dict = Depends(get_cu async def regenerate_token(slug: str, user: dict = Depends(get_current_user)): return await tracker_post(f"/api/v1/members/{slug}/regenerate-token") +@app.post("/api/v1/members/{slug}/revoke-token") +async def revoke_token(slug: str, user: dict = Depends(get_current_user)): + return await tracker_post(f"/api/v1/members/{slug}/revoke-token") + # --- Health --- diff --git a/src/components/AgentModal.tsx b/src/components/AgentModal.tsx index e9e0f99..2635f4f 100644 --- a/src/components/AgentModal.tsx +++ b/src/components/AgentModal.tsx @@ -1,7 +1,7 @@ "use client"; import { useState } from "react"; -import { Member, updateMember, regenerateToken } from "@/lib/api"; +import { Member, updateMember, regenerateToken, revokeToken } from "@/lib/api"; interface Props { agent: Member; @@ -19,9 +19,10 @@ export default function AgentModal({ agent, onClose, onUpdated }: Props) { const [prompt, setPrompt] = useState(agent.agent_config?.prompt || ""); const [model, setModel] = useState(agent.agent_config?.model || ""); const [saving, setSaving] = useState(false); - const [newToken, setNewToken] = useState(null); + const [currentToken, setCurrentToken] = useState(agent.token || null); const [copied, setCopied] = useState(false); const [confirmRegen, setConfirmRegen] = useState(false); + const [confirmRevoke, setConfirmRevoke] = useState(false); const handleSave = async () => { setSaving(true); @@ -49,16 +50,26 @@ export default function AgentModal({ agent, onClose, onUpdated }: Props) { const handleRegenerate = async () => { try { const { token } = await regenerateToken(agent.slug); - setNewToken(token); + setCurrentToken(token); setConfirmRegen(false); } catch (e) { console.error(e); } }; + const handleRevoke = async () => { + try { + await revokeToken(agent.slug); + setCurrentToken(null); + setConfirmRevoke(false); + } catch (e) { + console.error(e); + } + }; + const copyToken = () => { - if (newToken) { - navigator.clipboard.writeText(newToken); + if (currentToken) { + navigator.clipboard.writeText(currentToken); setCopied(true); setTimeout(() => setCopied(false), 2000); } @@ -157,45 +168,68 @@ export default function AgentModal({ agent, onClose, onUpdated }: Props) { {/* Token section */}
Токен доступа
- {newToken ? ( + {currentToken ? (
-
- ⚠️ Сохраните токен — он больше не будет показан! -
- {newToken} + {currentToken} +
+
+ + {confirmRegen ? ( + <> + + + + ) : ( + + )} + {confirmRevoke ? ( + <> + + + + ) : ( + + )}
- -
- ) : confirmRegen ? ( -
- Старый токен перестанет работать! - -
) : (
- Токен скрыт + Токен отозван
)} diff --git a/src/lib/api.ts b/src/lib/api.ts index 146cc78..176bf33 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -50,6 +50,7 @@ export interface Member { status: string; avatar_url: string | null; agent_config: AgentConfig | null; + token?: string | null; } export interface MemberCreateResponse extends Member { @@ -238,3 +239,7 @@ export async function updateMember(slug: string, data: { export async function regenerateToken(slug: string): Promise<{ token: string }> { return request(`/api/v1/members/${slug}/regenerate-token`, { method: "POST" }); } + +export async function revokeToken(slug: string): Promise { + await request(`/api/v1/members/${slug}/revoke-token`, { method: "POST" }); +}