Merge pull request #189 from slowlydev/feat/enable-autodeploy-github

Add web hook verification to GitHub Autodeploy
This commit is contained in:
Mauricio Siu 2024-07-02 18:02:06 -06:00 committed by GitHub
commit 3322fdf937
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 10269 additions and 6344 deletions

View File

@ -0,0 +1 @@
ALTER TABLE "admin" ADD COLUMN "githubWebhookSecret" text;

File diff suppressed because it is too large Load Diff

View File

@ -127,6 +127,13 @@
"when": 1719547174326,
"tag": "0017_minor_post",
"breakpoints": true
},
{
"idx": 18,
"version": "6",
"when": 1719928377858,
"tag": "0018_careful_killmonger",
"breakpoints": true
}
]
}

View File

@ -36,10 +36,12 @@
"@codemirror/lang-yaml": "^6.1.1",
"@codemirror/language": "^6.10.1",
"@codemirror/legacy-modes": "6.4.0",
"@dokploy/trpc-openapi": "0.0.4",
"@faker-js/faker": "^8.4.1",
"@hookform/resolvers": "^3.3.4",
"@lucia-auth/adapter-drizzle": "1.0.7",
"@octokit/auth-app": "^6.0.4",
"@octokit/webhooks": "^13.2.7",
"@radix-ui/react-accordion": "1.1.2",
"@radix-ui/react-alert-dialog": "^1.0.5",
"@radix-ui/react-avatar": "^1.0.4",
@ -113,7 +115,6 @@
"tailwind-merge": "^2.2.0",
"tailwindcss-animate": "^1.0.7",
"tar-fs": "3.0.5",
"@dokploy/trpc-openapi": "0.0.4",
"use-resize-observer": "9.1.0",
"ws": "8.16.0",
"xterm-addon-fit": "^0.8.0",

View File

@ -1,17 +1,39 @@
import { and, eq } from "drizzle-orm";
import { db } from "@/server/db";
import { Webhooks } from "@octokit/webhooks";
import type { NextApiRequest, NextApiResponse } from "next";
import { applications, compose } from "@/server/db/schema";
import { extractCommitMessage, extractHash } from "./[refreshToken]";
import type { DeploymentJob } from "@/server/queues/deployments-queue";
import { myQueue } from "@/server/queues/queueSetup";
export default async function handler(
req: NextApiRequest,
res: NextApiResponse,
) {
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const admin = await db.query.admins.findFirst({});
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 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") {
res.status(200).json({ message: "Ping received, webhook is active" });
return;
@ -33,7 +55,7 @@ export default async function handler(
eq(applications.sourceType, "github"),
eq(applications.autoDeploy, true),
eq(applications.branch, branchName),
eq(applications.repository, repository),
eq(applications.repository, repository)
),
});
@ -51,17 +73,12 @@ export default async function handler(
{
removeOnComplete: true,
removeOnFail: true,
},
}
);
}
const composeApps = await db.query.compose.findMany({
where: and(
eq(compose.sourceType, "github"),
eq(compose.autoDeploy, true),
eq(compose.branch, branchName),
eq(compose.repository, repository),
),
where: and(eq(compose.sourceType, "github"), eq(compose.autoDeploy, true), eq(compose.branch, branchName), eq(compose.repository, repository)),
});
for (const composeApp of composeApps) {
@ -79,7 +96,7 @@ export default async function handler(
{
removeOnComplete: true,
removeOnFail: true,
},
}
);
}

View File

@ -38,6 +38,7 @@ export default async function handler(
githubAppName: data.name,
githubClientId: data.client_id,
githubClientSecret: data.client_secret,
githubWebhookSecret: data.webhook_secret,
githubPrivateKey: data.pem,
})
.where(eq(admins.authId, authId as string))

File diff suppressed because it is too large Load Diff

View File

@ -23,6 +23,7 @@ export const admins = pgTable("admin", {
githubClientSecret: text("githubClientSecret"),
githubInstallationId: text("githubInstallationId"),
githubPrivateKey: text("githubPrivateKey"),
githubWebhookSecret: text("githubWebhookSecret"),
letsEncryptEmail: text("letsEncryptEmail"),
sshPrivateKey: text("sshPrivateKey"),
enableDockerCleanup: boolean("enableDockerCleanup").notNull().default(false),