mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-07-24 05:16:09 +00:00
feat(tenancy): implement workspace isolation
This commit is contained in:
@@ -40,12 +40,20 @@ import { PanelToolbar } from '../settings-dialog/panel-layout';
|
||||
|
||||
interface ApiKey {
|
||||
id: number;
|
||||
uuid: string;
|
||||
name: string;
|
||||
key: string;
|
||||
description: string;
|
||||
scopes: string[];
|
||||
status: 'active' | 'revoked';
|
||||
secret_available: false;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
type CreatedApiKey = Omit<ApiKey, 'secret_available'> & {
|
||||
key: string;
|
||||
secret_available: true;
|
||||
};
|
||||
|
||||
interface Webhook {
|
||||
id: number;
|
||||
name: string;
|
||||
@@ -71,7 +79,7 @@ export default function ApiIntegrationPanel({
|
||||
const [showCreateDialog, setShowCreateDialog] = useState(false);
|
||||
const [newKeyName, setNewKeyName] = useState('');
|
||||
const [newKeyDescription, setNewKeyDescription] = useState('');
|
||||
const [createdKey, setCreatedKey] = useState<ApiKey | null>(null);
|
||||
const [createdKey, setCreatedKey] = useState<CreatedApiKey | null>(null);
|
||||
const [deleteKeyId, setDeleteKeyId] = useState<number | null>(null);
|
||||
|
||||
// Webhook state
|
||||
@@ -135,7 +143,7 @@ export default function ApiIntegrationPanel({
|
||||
const response = (await backendClient.post('/api/v1/apikeys', {
|
||||
name: newKeyName,
|
||||
description: newKeyDescription,
|
||||
})) as { key: ApiKey };
|
||||
})) as { key: CreatedApiKey };
|
||||
|
||||
setCreatedKey(response.key);
|
||||
toast.success(t('common.apiKeyCreated'));
|
||||
@@ -184,11 +192,6 @@ export default function ApiIntegrationPanel({
|
||||
copiedTimerRef.current = setTimeout(() => setCopiedKey(null), 2000);
|
||||
};
|
||||
|
||||
const maskApiKey = (key: string) => {
|
||||
if (key.length <= 8) return key;
|
||||
return `${key.substring(0, 8)}...${key.substring(key.length - 4)}`;
|
||||
};
|
||||
|
||||
// Webhook methods
|
||||
const loadWebhooks = async () => {
|
||||
setLoading(true);
|
||||
@@ -337,25 +340,12 @@ export default function ApiIntegrationPanel({
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<code className="text-sm bg-muted px-2 py-1 rounded">
|
||||
{maskApiKey(item.key)}
|
||||
</code>
|
||||
<span className="text-sm text-muted-foreground">
|
||||
{t('common.apiKeyStoredSecurely')}
|
||||
</span>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<div className="flex gap-2">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
type="button"
|
||||
onClick={() => handleCopyKey(item.key)}
|
||||
title={t('common.copyApiKey')}
|
||||
>
|
||||
{copiedKey === item.key ? (
|
||||
<Check className="h-4 w-4 text-green-600" />
|
||||
) : (
|
||||
<Copy className="h-4 w-4" />
|
||||
)}
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
|
||||
Reference in New Issue
Block a user