298a7fa9de
Audit D2/D3/D4/D5: all four ApiTab buttons were handler-less and the fields were hardcoded. Adds api/apiKeys.ts + api/webhooks.ts modules and rewires ApiTab: loads the api-key prefix + webhook settings on mount; Copy -> clipboard + snackbar; Regenerate -> confirm dialog -> POST regenerate (full key shown once); Save Webhook -> PUT webhook-settings; Test Webhook -> POST test with the result in a snackbar. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
41 lines
1.3 KiB
TypeScript
41 lines
1.3 KiB
TypeScript
import { apiClient, ensureCsrfCookie } from './client';
|
||
|
||
/**
|
||
* Настройки исходящего webhook'а тенанта (audit D4/D5). Backend:
|
||
* WebhookSettingsController. Полный secret доступен только в ответе
|
||
* saveWebhookSettings() при первом создании подписки.
|
||
*/
|
||
export interface WebhookSettings {
|
||
target_url: string;
|
||
secret_prefix: string;
|
||
events: string[];
|
||
is_active: boolean;
|
||
}
|
||
|
||
export interface SavedWebhookSettings extends WebhookSettings {
|
||
secret?: string;
|
||
}
|
||
|
||
export interface WebhookTestResult {
|
||
ok: boolean;
|
||
status: number | null;
|
||
message: string;
|
||
}
|
||
|
||
export async function getWebhookSettings(): Promise<WebhookSettings | null> {
|
||
const { data } = await apiClient.get<{ data: WebhookSettings | null }>('/api/tenants/me/webhook-settings');
|
||
return data.data;
|
||
}
|
||
|
||
export async function saveWebhookSettings(payload: { target_url: string }): Promise<SavedWebhookSettings> {
|
||
await ensureCsrfCookie();
|
||
const { data } = await apiClient.put<{ data: SavedWebhookSettings }>('/api/tenants/me/webhook-settings', payload);
|
||
return data.data;
|
||
}
|
||
|
||
export async function testWebhook(): Promise<WebhookTestResult> {
|
||
await ensureCsrfCookie();
|
||
const { data } = await apiClient.post<WebhookTestResult>('/api/webhooks/test');
|
||
return data;
|
||
}
|