import { Router, Request } from "express"; import crypto from "crypto"; import { deploymentService } from "../services/deploymentService.js"; const router = Router(); type RawBodyRequest = Request & { rawBody?: Buffer }; function getHeaderValue(value: string | string[] | undefined) { if (!value) return ""; return Array.isArray(value) ? value[0] : value; } function verifySignature(rawBody: Buffer, secret: string, signature: string) { const cleaned = signature.startsWith("sha256=") ? signature.slice(7) : signature; const expected = crypto.createHmac("sha256", secret).update(rawBody).digest("hex"); if (cleaned.length !== expected.length) return false; return crypto.timingSafeEqual(Buffer.from(cleaned), Buffer.from(expected)); } router.post("/api/deployments/webhook/:token", async (req, res) => { const { token } = req.params; const settings = await deploymentService.ensureSettings(); const authHeader = getHeaderValue(req.headers.authorization); if (!authHeader) { return res.status(401).json({ message: "Yetkisiz" }); } const providedToken = authHeader.startsWith("Bearer ") ? authHeader.slice("Bearer ".length) : authHeader; if (providedToken !== settings.webhookToken) { return res.status(401).json({ message: "Yetkisiz" }); } const signatureHeader = getHeaderValue(req.headers["x-gitea-signature"]) || getHeaderValue(req.headers["x-gitea-signature-256"]); const rawBody = (req as RawBodyRequest).rawBody; if (!rawBody || !signatureHeader) { return res.status(401).json({ message: "Imza eksik" }); } if (!verifySignature(rawBody, settings.webhookSecret, signatureHeader)) { return res.status(401).json({ message: "Imza dogrulanamadi" }); } const payload = req.body as { ref?: string; head_commit?: { message?: string }; commits?: Array<{ message?: string }> }; const ref = payload?.ref || ""; const branch = ref.startsWith("refs/heads/") ? ref.replace("refs/heads/", "") : ref; const commitMessage = payload?.head_commit?.message || payload?.commits?.[payload.commits.length - 1]?.message; const project = await deploymentService.findByWebhookToken(token); if (!project) return res.status(404).json({ message: "Deployment bulunamadi" }); if (branch && branch !== project.branch) { return res.json({ ignored: true }); } deploymentService .runDeployment(project._id.toString(), commitMessage ? { message: commitMessage } : undefined) .catch(() => undefined); return res.json({ queued: true }); }); export default router;