feat: check webhook signature
All checks were successful
Build and Push Docker Image / build (push) Successful in 21s
All checks were successful
Build and Push Docker Image / build (push) Successful in 21s
This commit is contained in:
@@ -3,7 +3,9 @@ import { z } from "zod";
|
||||
|
||||
const schema = z.object({
|
||||
PORT: z.coerce.number(),
|
||||
GITEA_WEBHOOK_SECRET: z.string(),
|
||||
});
|
||||
|
||||
const result = schema.safeParse(process.env);
|
||||
if (!result.success) {
|
||||
console.error("ERROR: Environment variable validation failed:");
|
||||
|
||||
33
src/index.ts
33
src/index.ts
@@ -1,4 +1,5 @@
|
||||
import express from "express";
|
||||
import crypto from "crypto";
|
||||
import { z } from "zod";
|
||||
import { env } from "./env";
|
||||
|
||||
@@ -8,12 +9,38 @@ const webhookSchema = z.object({
|
||||
|
||||
const app = express();
|
||||
|
||||
app.use(express.json());
|
||||
app.use(
|
||||
express.raw({
|
||||
inflate: true,
|
||||
limit: "100kb",
|
||||
type: "application/json",
|
||||
}),
|
||||
);
|
||||
|
||||
app.post("/", async (req, res) => {
|
||||
const result = webhookSchema.safeParse(req.body);
|
||||
const signature = req.headers["x-gitea-signature"] as string | undefined;
|
||||
if (!signature) {
|
||||
console.error("x-gitea-signature missing");
|
||||
res.sendStatus(401);
|
||||
return;
|
||||
}
|
||||
|
||||
const hmac = crypto.createHmac("sha256", env.GITEA_WEBHOOK_SECRET);
|
||||
hmac.update(req.body);
|
||||
const payloadSignature = hmac.digest("hex");
|
||||
|
||||
if (signature !== payloadSignature) {
|
||||
console.error("signature !== payload_signature");
|
||||
res.sendStatus(401);
|
||||
return;
|
||||
}
|
||||
|
||||
const json = JSON.parse(req.body.toString());
|
||||
const result = webhookSchema.safeParse(json);
|
||||
|
||||
if (!result.success) {
|
||||
res.sendStatus(200);
|
||||
console.error("Invalid webhook payload:", result.error.issues);
|
||||
res.sendStatus(400);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user