feat: per-group webhook ingress, custom webhooks, GitHub App tenant isolation

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.
This commit is contained in:
RhenCloud 2026-08-13 09:24:50 +08:00
parent 0b078d938b
commit b600f02027
No known key found for this signature in database
GPG key ID: A574A617378C4E0B
34 changed files with 1711 additions and 183 deletions

View file

@ -114,6 +114,13 @@ export interface Group {
* (e.g. `["github"]`, `["gitea"]`). Empty/omitted = all providers.
*/
providers?: WebhookProvider[];
/**
* GitHub App installation id bound to this group. When set, only webhook
* events coming from that installation (org/user) are accepted into the
* group's routes hard tenant isolation on top of (or instead of) the
* `owners` list. Empty/omitted = no installation restriction.
*/
installationId?: number;
/**
* Whether to include emoji in messages sent through this group's routes.
* Defaults to true when omitted.
@ -137,7 +144,7 @@ export interface Filter {
exclude?: boolean;
}
export type WebhookProvider = "github" | "gitea" | "gitlab";
export type WebhookProvider = "github" | "gitea" | "gitlab" | "custom";
export interface WebhookEvent {
event: string;
@ -145,6 +152,11 @@ export interface WebhookEvent {
signature?: string;
deliveryId?: string;
provider?: WebhookProvider;
/**
* GitHub App installation id that produced this event (extracted from
* `payload.installation.id`). Gitea/custom events have none.
*/
installationId?: number;
}
export interface NeutralAuthor {