mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
feat(deploy-github): add webhook secret verification before deploying
This commit is contained in:
@@ -1,17 +1,39 @@
|
|||||||
import { and, eq } from "drizzle-orm";
|
import { and, eq } from "drizzle-orm";
|
||||||
import { db } from "@/server/db";
|
import { db } from "@/server/db";
|
||||||
|
import { Webhooks } from "@octokit/webhooks";
|
||||||
import type { NextApiRequest, NextApiResponse } from "next";
|
import type { NextApiRequest, NextApiResponse } from "next";
|
||||||
import { applications, compose } from "@/server/db/schema";
|
import { applications, compose } from "@/server/db/schema";
|
||||||
import { extractCommitMessage, extractHash } from "./[refreshToken]";
|
import { extractCommitMessage, extractHash } from "./[refreshToken]";
|
||||||
import type { DeploymentJob } from "@/server/queues/deployments-queue";
|
import type { DeploymentJob } from "@/server/queues/deployments-queue";
|
||||||
import { myQueue } from "@/server/queues/queueSetup";
|
import { myQueue } from "@/server/queues/queueSetup";
|
||||||
|
|
||||||
export default async function handler(
|
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||||
req: NextApiRequest,
|
const admin = await db.query.admins.findFirst({});
|
||||||
res: NextApiResponse,
|
|
||||||
) {
|
if (!admin) {
|
||||||
|
res.status(200).json({ message: "Could not find admin" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!admin.githubWebhookSecret) {
|
||||||
|
res.status(200).json({ message: "Github Webhook Secret not set" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const webhooks = new Webhooks({
|
||||||
|
secret: admin.githubWebhookSecret,
|
||||||
|
});
|
||||||
|
|
||||||
|
const signature = req.headers["x-hub-signature-256"];
|
||||||
const github = req.body;
|
const github = req.body;
|
||||||
|
|
||||||
|
const verified = await webhooks.verify(JSON.stringify(github), signature as string);
|
||||||
|
|
||||||
|
if (!verified) {
|
||||||
|
res.status(401).json({ message: "Unauthorized" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (req.headers["x-github-event"] === "ping") {
|
if (req.headers["x-github-event"] === "ping") {
|
||||||
res.status(200).json({ message: "Ping received, webhook is active" });
|
res.status(200).json({ message: "Ping received, webhook is active" });
|
||||||
return;
|
return;
|
||||||
@@ -33,7 +55,7 @@ export default async function handler(
|
|||||||
eq(applications.sourceType, "github"),
|
eq(applications.sourceType, "github"),
|
||||||
eq(applications.autoDeploy, true),
|
eq(applications.autoDeploy, true),
|
||||||
eq(applications.branch, branchName),
|
eq(applications.branch, branchName),
|
||||||
eq(applications.repository, repository),
|
eq(applications.repository, repository)
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -51,17 +73,12 @@ export default async function handler(
|
|||||||
{
|
{
|
||||||
removeOnComplete: true,
|
removeOnComplete: true,
|
||||||
removeOnFail: true,
|
removeOnFail: true,
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const composeApps = await db.query.compose.findMany({
|
const composeApps = await db.query.compose.findMany({
|
||||||
where: and(
|
where: and(eq(compose.sourceType, "github"), eq(compose.autoDeploy, true), eq(compose.branch, branchName), eq(compose.repository, repository)),
|
||||||
eq(compose.sourceType, "github"),
|
|
||||||
eq(compose.autoDeploy, true),
|
|
||||||
eq(compose.branch, branchName),
|
|
||||||
eq(compose.repository, repository),
|
|
||||||
),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const composeApp of composeApps) {
|
for (const composeApp of composeApps) {
|
||||||
@@ -79,7 +96,7 @@ export default async function handler(
|
|||||||
{
|
{
|
||||||
removeOnComplete: true,
|
removeOnComplete: true,
|
||||||
removeOnFail: true,
|
removeOnFail: true,
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user