Merge branch 'canary' into feat/requests

This commit is contained in:
Mauricio Siu
2024-09-05 00:17:40 -06:00
189 changed files with 22323 additions and 2667 deletions

View File

@@ -66,6 +66,18 @@ export default async function handler(
res.status(301).json({ message: "Branch Not Match" });
return;
}
} else if (sourceType === "gitlab") {
const branchName = extractBranchName(req.headers, req.body);
if (!branchName || branchName !== application.gitlabBranch) {
res.status(301).json({ message: "Branch Not Match" });
return;
}
} else if (sourceType === "bitbucket") {
const branchName = extractBranchName(req.headers, req.body);
if (!branchName || branchName !== application.bitbucketBranch) {
res.status(301).json({ message: "Branch Not Match" });
return;
}
}
try {

View File

@@ -1,6 +1,6 @@
import { findAdmin } from "@/server/api/services/admin";
import { db } from "@/server/db";
import { applications, compose } from "@/server/db/schema";
import { applications, compose, github } from "@/server/db/schema";
import type { DeploymentJob } from "@/server/queues/deployments-queue";
import { myQueue } from "@/server/queues/queueSetup";
import { Webhooks } from "@octokit/webhooks";
@@ -19,20 +19,33 @@ export default async function handler(
return;
}
if (!admin.githubWebhookSecret) {
res.status(200).json({ message: "Github Webhook Secret not set" });
const signature = req.headers["x-hub-signature-256"];
const githubBody = req.body;
if (!githubBody?.installation.id) {
res.status(400).json({ message: "Github Installation not found" });
return;
}
const webhooks = new Webhooks({
secret: admin.githubWebhookSecret,
const githubResult = await db.query.github.findFirst({
where: eq(github.githubInstallationId, githubBody.installation.id),
});
const signature = req.headers["x-hub-signature-256"];
const github = req.body;
if (!githubResult) {
res.status(400).json({ message: "Github Installation not found" });
return;
}
if (!githubResult.githubWebhookSecret) {
res.status(400).json({ message: "Github Webhook Secret not set" });
return;
}
const webhooks = new Webhooks({
secret: githubResult.githubWebhookSecret,
});
const verified = await webhooks.verify(
JSON.stringify(github),
JSON.stringify(githubBody),
signature as string,
);
@@ -52,8 +65,8 @@ export default async function handler(
}
try {
const branchName = github?.ref?.replace("refs/heads/", "");
const repository = github?.repository?.name;
const branchName = githubBody?.ref?.replace("refs/heads/", "");
const repository = githubBody?.repository?.name;
const deploymentTitle = extractCommitMessage(req.headers, req.body);
const deploymentHash = extractHash(req.headers, req.body);

View File

@@ -1,5 +1,6 @@
import { createGithub } from "@/server/api/services/github";
import { db } from "@/server/db";
import { admins } from "@/server/db/schema";
import { github } from "@/server/db/schema";
import { eq } from "drizzle-orm";
import type { NextApiRequest, NextApiResponse } from "next";
import { Octokit } from "octokit";
@@ -17,10 +18,12 @@ export default async function handler(
) {
const { code, state, installation_id, setup_action }: Query =
req.query as Query;
if (!code) {
return res.status(400).json({ error: "Missing code parameter" });
}
const [action, authId] = state?.split(":");
const [action, value] = state?.split(":");
// Value could be the authId or the githubProviderId
if (action === "gh_init") {
const octokit = new Octokit({});
@@ -31,27 +34,25 @@ export default async function handler(
},
);
const result = await db
.update(admins)
.set({
githubAppId: data.id,
githubAppName: data.html_url,
githubClientId: data.client_id,
githubClientSecret: data.client_secret,
githubWebhookSecret: data.webhook_secret,
githubPrivateKey: data.pem,
})
.where(eq(admins.authId, authId as string))
.returning();
await createGithub({
name: data.name,
githubAppName: data.html_url,
githubAppId: data.id,
githubClientId: data.client_id,
githubClientSecret: data.client_secret,
githubWebhookSecret: data.webhook_secret,
githubPrivateKey: data.pem,
authId: value as string,
});
} else if (action === "gh_setup") {
await db
.update(admins)
.update(github)
.set({
githubInstallationId: installation_id,
})
.where(eq(admins.authId, authId as string))
.where(eq(github.githubId, value as string))
.returning();
}
res.redirect(307, "/dashboard/settings/server");
res.redirect(307, "/dashboard/settings/git-providers");
}

View File

@@ -8,9 +8,9 @@ export default async function handler(
const xGitHubEvent = req.headers["x-github-event"];
if (xGitHubEvent === "ping") {
res.redirect(307, "/dashboard/settings");
res.redirect(307, "/dashboard/settings/git-providers");
} else {
res.redirect(307, "/dashboard/settings");
res.redirect(307, "/dashboard/settings/git-providers");
}
} else {
res.setHeader("Allow", ["POST"]);

View File

@@ -0,0 +1,44 @@
import { findGitlabById, updateGitlab } from "@/server/api/services/gitlab";
import type { NextApiRequest, NextApiResponse } from "next";
export default async function handler(
req: NextApiRequest,
res: NextApiResponse,
) {
const { code, gitlabId } = req.query;
if (!code || Array.isArray(code)) {
return res.status(400).json({ error: "Missing or invalid code" });
}
const gitlab = await findGitlabById(gitlabId as string);
const response = await fetch("https://gitlab.com/oauth/token", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams({
client_id: gitlab.applicationId as string,
client_secret: gitlab.secret as string,
code: code as string,
grant_type: "authorization_code",
redirect_uri: `${gitlab.redirectUri}?gitlabId=${gitlabId}`,
}),
});
const result = await response.json();
if (!result.access_token || !result.refresh_token) {
return res.status(400).json({ error: "Missing or invalid code" });
}
const expiresAt = Math.floor(Date.now() / 1000) + result.expires_in;
await updateGitlab(gitlab.gitlabId, {
accessToken: result.access_token,
refreshToken: result.refresh_token,
expiresAt,
});
return res.redirect(307, "/dashboard/settings/git-providers");
}

View File

@@ -0,0 +1,81 @@
import { ShowGitProviders } from "@/components/dashboard/settings/git/show-git-providers";
import { DashboardLayout } from "@/components/layouts/dashboard-layout";
import { SettingsLayout } from "@/components/layouts/settings-layout";
import { appRouter } from "@/server/api/root";
import { validateRequest } from "@/server/auth/auth";
import { createServerSideHelpers } from "@trpc/react-query/server";
import type { GetServerSidePropsContext } from "next";
import React, { type ReactElement } from "react";
import superjson from "superjson";
const Page = () => {
return (
<div className="flex flex-col gap-4 w-full">
<ShowGitProviders />
</div>
);
};
export default Page;
Page.getLayout = (page: ReactElement) => {
return (
<DashboardLayout tab={"settings"}>
<SettingsLayout>{page}</SettingsLayout>
</DashboardLayout>
);
};
export async function getServerSideProps(
ctx: GetServerSidePropsContext<{ serviceId: string }>,
) {
const { user, session } = await validateRequest(ctx.req, ctx.res);
if (!user) {
return {
redirect: {
permanent: true,
destination: "/",
},
};
}
const { req, res } = ctx;
const helpers = createServerSideHelpers({
router: appRouter,
ctx: {
req: req as any,
res: res as any,
db: null as any,
session: session,
user: user,
},
transformer: superjson,
});
try {
await helpers.project.all.prefetch();
const auth = await helpers.auth.get.fetch();
if (auth.rol === "user") {
const user = await helpers.user.byAuthId.fetch({
authId: auth.id,
});
if (!user.canAccessToGitProviders) {
return {
redirect: {
permanent: true,
destination: "/",
},
};
}
}
return {
props: {
trpcState: helpers.dehydrate(),
},
};
} catch (error) {
return {
props: {},
};
}
}

View File

@@ -1,4 +1,3 @@
import { GithubSetup } from "@/components/dashboard/settings/github/github-setup";
import { WebDomain } from "@/components/dashboard/settings/web-domain";
import { WebServer } from "@/components/dashboard/settings/web-server";
import { DashboardLayout } from "@/components/layouts/dashboard-layout";
@@ -11,7 +10,6 @@ const Page = () => {
return (
<div className="flex flex-col gap-4 w-full">
<WebDomain />
<GithubSetup />
<WebServer />
</div>
);