Skip to content

Commit

Permalink
gh app webhook
Browse files Browse the repository at this point in the history
  • Loading branch information
Aslemammad committed Mar 21, 2024
1 parent b5bc2fb commit fc8493e
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 3 deletions.
14 changes: 14 additions & 0 deletions packages/backend/nitro.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,23 @@ declare module "nitro-cloudflare-dev" {
}
}

declare module "nitropack" {
interface NitroRuntimeConfig {
appId: string
webhookSecret: string
privateKey: string
}
}

// https://nitro.unjs.io/config
export default defineNitroConfig({
preset: 'cloudflare-pages',
modules: [ncb],
srcDir: "server",

runtimeConfig: {
appId: "",
webhookSecret: "",
privateKey: ""
}
});
113 changes: 111 additions & 2 deletions packages/backend/server/routes/webhook.post.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,112 @@
export default eventHandler((event) => {
console.log(event)
import { App } from "octokit";

export default eventHandler(async (event) => {
const { appId, privateKey, webhookSecret } = useRuntimeConfig(event);
const app = new App({
appId,
privateKey,
webhooks: {
secret: webhookSecret,
},
});
app.webhooks.on("workflow_job", ({ octokit, payload }) => {
console.log(payload)
});
// event.context.cloudflare.request.

type EmitterWebhookEvent = Parameters<typeof app.webhooks.receive>[0]
const id: EmitterWebhookEvent['id'] = event.headers.get("x-github-delivery");
const name = event.headers.get("x-github-event") as EmitterWebhookEvent['name'];
const signature = event.headers.get("x-hub-signature-256") ?? "";
const payloadString = await event.context.cloudflare.request.text();
const payload: EmitterWebhookEvent['payload'] = JSON.parse(payloadString);

// Verify webhook signature
try {
await verifyWebhookSignature(payloadString, signature, webhookSecret);
} catch (error) {
app.log.warn(error.message);
return new Response(`{ "error": "${error.message}" }`, {
status: 400,
headers: { "content-type": "application/json" },
});
}

// Now handle the request
try {
await app.webhooks.receive({
id,
name,
payload,
} as EmitterWebhookEvent);

return new Response(`{ "ok": true }`, {
headers: { "content-type": "application/json" },
});
} catch (error) {
app.log.error(error);

return new Response(`{ "error": "${error.message}" }`, {
status: 500,
headers: { "content-type": "application/json" },
});
}
});

// https://github.com/gr2m/cloudflare-worker-github-app-example/blob/main/lib/verify.js
export async function verifyWebhookSignature(
payload: string,
signature: string,
secret: string
) {
if (!signature) {
throw new Error("Signature is missing");
} else if (!signature.startsWith("sha256=")) {
throw new Error("Invalid signature format");
}

const algorithm = { name: "HMAC", hash: "SHA-256" };
const enc = new TextEncoder();
const key = await crypto.subtle.importKey(
"raw",
enc.encode(secret),
algorithm,
false,
["sign", "verify"]
);

const signed = await crypto.subtle.sign(
algorithm.name,
key,
enc.encode(payload)
);
const expectedSignature = "sha256=" + array2hex(signed);
if (!safeCompare(expectedSignature, signature)) {
throw new Error("Signature does not match event payload and secret");
}

// All good!
}

function array2hex(arr: ArrayBuffer) {
return [...new Uint8Array(arr)]
.map((x) => x.toString(16).padStart(2, "0"))
.join("");
}

/** Constant-time string comparison */
function safeCompare(expected: string, actual: string) {
const lenExpected = expected.length;
let result = 0;

if (lenExpected !== actual.length) {
actual = expected;
result = 1;
}

for (let i = 0; i < lenExpected; i++) {
result |= expected.charCodeAt(i) ^ actual.charCodeAt(i);
}

return result === 0;
}
1 change: 0 additions & 1 deletion packages/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ const eventPayload = await import(process.env.GITHUB_EVENT_PATH, {
with: { type: "json" },
});

console.log(process.env)
// console.log(octokit)
// console.log(eventPayload)

Expand Down

0 comments on commit fc8493e

Please sign in to comment.