Sign webhook requests (#4156)

Co-authored-by: Tom Moor <tom.moor@gmail.com>
This commit is contained in:
Apoorv Mishra
2022-09-25 02:49:26 +05:30
committed by GitHub
parent 75fb0826c5
commit 7a590550c9
9 changed files with 139 additions and 6 deletions

View File

@@ -70,6 +70,33 @@ describe("DeliverWebhookTask", () => {
expect(delivery.responseBody).toEqual("SUCCESS");
});
test("should hit the subscription url with signature header", async () => {
const subscription = await buildWebhookSubscription({
url: "http://example.com",
events: ["*"],
secret: "secret",
});
const signedInUser = await buildUser({ teamId: subscription.teamId });
const processor = new DeliverWebhookTask();
const event: UserEvent = {
name: "users.signin",
userId: signedInUser.id,
teamId: subscription.teamId,
actorId: signedInUser.id,
ip,
};
await processor.perform({
subscriptionId: subscription.id,
event,
});
const headers = fetchMock.mock.calls[0]![1]!.headers!;
expect(fetchMock).toHaveBeenCalledTimes(1);
expect(headers["Outline-Signature"]).toMatch(/^t=[0-9]+,s=[a-z0-9]+$/);
});
test("should hit the subscription url when the eventing model doesn't exist", async () => {
const subscription = await buildWebhookSubscription({
url: "http://example.com",

View File

@@ -209,12 +209,20 @@ export default class DeliverWebhookTask extends BaseTask<Props> {
paranoid: false,
});
let data = null;
if (model) {
data = {
...presentWebhookSubscription(model),
secret: undefined,
};
}
await this.sendWebhook({
event,
subscription,
payload: {
id: event.modelId,
model: model && presentWebhookSubscription(model),
model: data,
},
});
}
@@ -540,6 +548,12 @@ export default class DeliverWebhookTask extends BaseTask<Props> {
env.VERSION ? `/${env.VERSION.slice(0, 7)}` : ""
}`,
};
const signature = subscription.signature(JSON.stringify(requestBody));
if (signature) {
requestHeaders["Outline-Signature"] = signature;
}
response = await fetch(subscription.url, {
method: "POST",
headers: requestHeaders,