fix(webhooks): update github webhook validation

This commit is contained in:
Mauricio Siu
2024-09-01 14:51:03 -06:00
parent e609714f1e
commit f05c811bdc
2 changed files with 106 additions and 96 deletions

View File

@@ -44,100 +44,102 @@ export const ShowGitProviders = () => {
</div> </div>
</CardContent> </CardContent>
</Card> </Card>
{data?.map((gitProvider, index) => { <div className="grid gap-4 sm:grid-cols-1 md:grid-cols-1">
const isGithub = gitProvider.providerType === "github"; {data?.map((gitProvider, index) => {
const isGitlab = gitProvider.providerType === "gitlab"; const isGithub = gitProvider.providerType === "github";
const haveGithubRequirements = const isGitlab = gitProvider.providerType === "gitlab";
gitProvider.providerType === "github" && const haveGithubRequirements =
gitProvider.github?.githubPrivateKey && gitProvider.providerType === "github" &&
gitProvider.github?.githubAppId && gitProvider.github?.githubPrivateKey &&
gitProvider.github?.githubInstallationId; gitProvider.github?.githubAppId &&
gitProvider.github?.githubInstallationId;
const haveGitlabRequirements = const haveGitlabRequirements =
gitProvider.gitlab?.accessToken && gitProvider.gitlab?.refreshToken; gitProvider.gitlab?.accessToken && gitProvider.gitlab?.refreshToken;
return ( return (
<div <div
className="space-y-4" className="space-y-4"
key={`${gitProvider.gitProviderId}-${index}`} key={`${gitProvider.gitProviderId}-${index}`}
> >
<Card className="flex sm:flex-row max-sm:gap-2 flex-col justify-between items-center p-4"> <Card className="flex sm:flex-row max-sm:gap-2 flex-col justify-between items-center p-4 h-full">
<div className="flex items-center space-x-4 w-full"> <div className="flex items-center space-x-4 w-full">
{gitProvider.providerType === "github" && ( {gitProvider.providerType === "github" && (
<GithubIcon className="w-6 h-6" /> <GithubIcon className="w-6 h-6" />
)} )}
{gitProvider.providerType === "gitlab" && ( {gitProvider.providerType === "gitlab" && (
<GitlabIcon className="w-6 h-6" /> <GitlabIcon className="w-6 h-6" />
)} )}
{gitProvider.providerType === "bitbucket" && ( {gitProvider.providerType === "bitbucket" && (
<BitbucketIcon className="w-6 h-6" /> <BitbucketIcon className="w-6 h-6" />
)} )}
<div> <div>
<p className="font-medium"> <p className="font-medium">
{gitProvider.providerType === "github" {gitProvider.providerType === "github"
? "GitHub" ? "GitHub"
: gitProvider.providerType === "gitlab" : gitProvider.providerType === "gitlab"
? "GitLab" ? "GitLab"
: "Bitbucket"} : "Bitbucket"}
</p> </p>
<p className="text-sm text-muted-foreground"> <p className="text-sm text-muted-foreground">
{gitProvider.name} {gitProvider.name}
</p> </p>
</div>
</div> </div>
</div> <div className="flex sm:gap-4 sm:flex-row flex-col">
<div className="flex sm:gap-4 sm:flex-row flex-col"> {!haveGithubRequirements && isGithub && (
{!haveGithubRequirements && isGithub && ( <div className="flex flex-col gap-1">
<div className="flex flex-col gap-1"> <Link
<Link href={`${gitProvider?.github?.githubAppName}/installations/new?state=gh_setup:${gitProvider?.github.githubId}`}
href={`${gitProvider?.github?.githubAppName}/installations/new?state=gh_setup:${gitProvider?.github.githubId}`} className={buttonVariants({ className: "w-fit" })}
className={buttonVariants({ className: "w-fit" })} >
> Install Github App
Install Github App </Link>
</Link> </div>
</div> )}
)}
{haveGithubRequirements && isGithub && ( {haveGithubRequirements && isGithub && (
<div className="flex flex-col gap-1"> <div className="flex flex-col gap-1">
<Link <Link
href={`${gitProvider?.github?.githubAppName}`} href={`${gitProvider?.github?.githubAppName}`}
target="_blank" target="_blank"
className={buttonVariants({ className={buttonVariants({
className: "w-fit", className: "w-fit",
variant: "secondary", variant: "secondary",
})} })}
> >
<span className="text-sm">Manage Github App</span> <span className="text-sm">Manage Github App</span>
</Link> </Link>
</div> </div>
)} )}
{!haveGitlabRequirements && isGitlab && ( {!haveGitlabRequirements && isGitlab && (
<div className="flex flex-col gap-1"> <div className="flex flex-col gap-1">
<Link <Link
href={getGitlabUrl( href={getGitlabUrl(
gitProvider.gitlab?.applicationId || "", gitProvider.gitlab?.applicationId || "",
gitProvider.gitlab?.gitlabId || "", gitProvider.gitlab?.gitlabId || "",
)} )}
target="_blank" target="_blank"
className={buttonVariants({ className={buttonVariants({
className: "w-fit", className: "w-fit",
variant: "secondary", variant: "secondary",
})} })}
> >
<span className="text-sm">Install Gitlab App</span> <span className="text-sm">Install Gitlab App</span>
</Link> </Link>
</div> </div>
)} )}
<RemoveGitProvider <RemoveGitProvider
gitProviderId={gitProvider.gitProviderId} gitProviderId={gitProvider.gitProviderId}
gitProviderType={gitProvider.providerType} gitProviderType={gitProvider.providerType}
/> />
</div> </div>
</Card> </Card>
</div> </div>
); );
})} })}
</div>
</div> </div>
); );
}; };

View File

@@ -1,6 +1,6 @@
import { findAdmin } from "@/server/api/services/admin"; import { findAdmin } from "@/server/api/services/admin";
import { db } from "@/server/db"; import { db } from "@/server/db";
import { applications, compose } from "@/server/db/schema"; import { applications, compose, githubProvider } from "@/server/db/schema";
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";
import { Webhooks } from "@octokit/webhooks"; import { Webhooks } from "@octokit/webhooks";
@@ -19,18 +19,26 @@ export default async function handler(
return; return;
} }
if (!admin.githubWebhookSecret) { const signature = req.headers["x-hub-signature-256"];
res.status(200).json({ message: "Github Webhook Secret not set" }); const github = req.body;
const githubResult = await db.query.githubProvider.findFirst({
where: eq(githubProvider.githubInstallationId, github.installation.id),
});
if (!githubResult) {
res.status(400).json({ message: "Github Installation not found" });
return; return;
} }
if (!githubResult.githubWebhookSecret) {
res.status(400).json({ message: "Github Webhook Secret not set" });
return;
}
const webhooks = new Webhooks({ const webhooks = new Webhooks({
secret: admin.githubWebhookSecret, secret: githubResult.githubWebhookSecret,
}); });
const signature = req.headers["x-hub-signature-256"];
const github = req.body;
const verified = await webhooks.verify( const verified = await webhooks.verify(
JSON.stringify(github), JSON.stringify(github),
signature as string, signature as string,