mirror of
https://github.com/ReCloudStudio/WebHooker.git
synced 2026-09-22 16:11:29 +00:00
Add POST /webhook/{groupId} with per-group secrets (KV tenant:{groupId}), a custom provider (X-WebHooker-Signature HMAC, arbitrary JSON -> custom events through the route pipeline), and GitHub App installation isolation (Group.installationId) with automatic provisioning on installation.created (inst-{id} groups or binding matching owners groups). Includes WebhookPanel admin UI, custom route template, docs and 157 passing tests.
50 lines
1.4 KiB
TypeScript
50 lines
1.4 KiB
TypeScript
export interface GroupWebhookInfo {
|
|
url: string;
|
|
hasSecret: boolean;
|
|
secret?: string;
|
|
}
|
|
|
|
export function useWebhookApi() {
|
|
const loading = ref(false);
|
|
const error = ref("");
|
|
|
|
async function request<T>(path: string, init?: RequestInit): Promise<T> {
|
|
loading.value = true;
|
|
error.value = "";
|
|
try {
|
|
const res = await fetch(path, {
|
|
headers: { accept: "application/json" },
|
|
credentials: "same-origin",
|
|
...init,
|
|
});
|
|
if (!res.ok) {
|
|
const data = (await res.json().catch(() => ({}))) as { error?: string };
|
|
throw new Error(data.error ?? `HTTP ${res.status}`);
|
|
}
|
|
return (await res.json()) as T;
|
|
} catch (err) {
|
|
error.value = err instanceof Error ? err.message : String(err);
|
|
throw err;
|
|
} finally {
|
|
loading.value = false;
|
|
}
|
|
}
|
|
|
|
function info(groupId: string): Promise<GroupWebhookInfo> {
|
|
return request(`/admin/api/groups/${encodeURIComponent(groupId)}/webhook`);
|
|
}
|
|
|
|
function regenerate(groupId: string): Promise<GroupWebhookInfo> {
|
|
return request(`/admin/api/groups/${encodeURIComponent(groupId)}/webhook/regenerate`, {
|
|
method: "POST",
|
|
});
|
|
}
|
|
|
|
function disable(groupId: string): Promise<{ ok: boolean }> {
|
|
return request(`/admin/api/groups/${encodeURIComponent(groupId)}/webhook`, {
|
|
method: "DELETE",
|
|
});
|
|
}
|
|
|
|
return { loading, error, info, regenerate, disable };
|
|
}
|