mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
feat(providers): add gitlab bitbucket and github providers
This commit is contained in:
58
apps/dokploy/pages/api/providers/github/redirect.ts
Normal file
58
apps/dokploy/pages/api/providers/github/redirect.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import { createGithubProvider } from "@/server/api/services/git-provider";
|
||||
import { db } from "@/server/db";
|
||||
import { githubProvider } from "@/server/db/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { Octokit } from "octokit";
|
||||
|
||||
type Query = {
|
||||
code: string;
|
||||
state: string;
|
||||
installation_id: string;
|
||||
setup_action: string;
|
||||
};
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
) {
|
||||
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, value] = state?.split(":");
|
||||
// Value could be the authId or the githubProviderId
|
||||
|
||||
if (action === "gh_init") {
|
||||
const octokit = new Octokit({});
|
||||
const { data } = await octokit.request(
|
||||
"POST /app-manifests/{code}/conversions",
|
||||
{
|
||||
code: code as string,
|
||||
},
|
||||
);
|
||||
|
||||
await createGithubProvider({
|
||||
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(githubProvider)
|
||||
.set({
|
||||
githubInstallationId: installation_id,
|
||||
})
|
||||
.where(eq(githubProvider.githubProviderId, value as string))
|
||||
.returning();
|
||||
}
|
||||
|
||||
res.redirect(307, "/dashboard/settings/git-providers");
|
||||
}
|
||||
19
apps/dokploy/pages/api/providers/github/webhook.ts
Normal file
19
apps/dokploy/pages/api/providers/github/webhook.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
) {
|
||||
if (req.method === "POST") {
|
||||
const xGitHubEvent = req.headers["x-github-event"];
|
||||
|
||||
if (xGitHubEvent === "ping") {
|
||||
res.redirect(307, "/dashboard/settings/git-providers");
|
||||
} else {
|
||||
res.redirect(307, "/dashboard/settings/git-providers");
|
||||
}
|
||||
} else {
|
||||
res.setHeader("Allow", ["POST"]);
|
||||
return res.status(405).end(`Method ${req.method} not allowed`);
|
||||
}
|
||||
}
|
||||
80
apps/dokploy/pages/api/providers/gitlab/callback.ts
Normal file
80
apps/dokploy/pages/api/providers/gitlab/callback.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import {
|
||||
getGitlabProvider,
|
||||
updateGitlabProvider,
|
||||
} from "@/server/api/services/git-provider";
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
) {
|
||||
console.log(req.body);
|
||||
const { code, gitlabId } = req.query;
|
||||
|
||||
if (!code || Array.isArray(code)) {
|
||||
return res.status(400).json({ error: "Missing or invalid code" });
|
||||
}
|
||||
|
||||
const gitlab = await getGitlabProvider(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 updatedGiltab = await updateGitlabProvider(gitlab.gitlabProviderId, {
|
||||
accessToken: result.access_token,
|
||||
refreshToken: result.refresh_token,
|
||||
});
|
||||
|
||||
return res.redirect(307, "/dashboard/settings/git-providers");
|
||||
}
|
||||
// b7262a56a0e84690d6352e07147e0cc4ff862818efe93a5fc7a12dc99a1382fd
|
||||
// {
|
||||
// accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
|
||||
// host: 'localhost:3000',
|
||||
// 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36',
|
||||
// 'accept-encoding': 'gzip, deflate, br, zstd',
|
||||
// 'accept-language': 'es-ES,es;q=0.9',
|
||||
// 'cache-control': 'max-age=0',
|
||||
// referer: 'https://gitlab.com/',
|
||||
// 'x-request-id': '3e925ffc549f9a3d3ef5d5f376c2a6f0',
|
||||
// 'x-real-ip': '10.240.3.64',
|
||||
// 'x-forwarded-port': '443',
|
||||
// 'x-forwarded-scheme': 'https',
|
||||
// 'x-original-uri': '/api/providers/gitlab/callback?code=f26181b5c7397444ace5211f9ac4683b2d7bd64cd9431e85d3b6b4722827fabf',
|
||||
// 'x-scheme': 'https',
|
||||
// 'sec-fetch-site': 'cross-site',
|
||||
// 'sec-fetch-mode': 'navigate',
|
||||
// 'sec-fetch-user': '?1',
|
||||
// 'sec-fetch-dest': 'document',
|
||||
// 'sec-ch-ua': '"Chromium";v="128", "Not;A=Brand";v="24", "Google Chrome";v="128"',
|
||||
// 'sec-ch-ua-mobile': '?0',
|
||||
// 'sec-ch-ua-platform': '"macOS"',
|
||||
// priority: 'u=0, i',
|
||||
// 'x-original-proto': 'https',
|
||||
// cookie: 'rl_anonymous_id=RS_ENC_v3_IjEzMzVhYzg0LTIyYjctNGExNi04YzE5LTg4M2ZiOTEwMTRmYSI%3D; rl_page_init_referrer=RS_ENC_v3_IiRkaXJlY3Qi; __adroll_fpc=7113966cdd8d59aba5e5ef62ff22c535-1715634343969; rl_session=RS_ENC_v3_eyJpZCI6MTcxNTYzNDM0Mzc1NiwiZXhwaXJlc0F0IjoxNzE1NjM3MDY5NDg1LCJ0aW1lb3V0IjoxODAwMDAwLCJhdXRvVHJhY2siOnRydWV9; _ga_65LBX6LVJK=GS1.1.1715634344.1.1.1715635269.0.0.0; __ar_v4=FZBVRO7FTNEL3NZLTQLETP%3A20240512%3A9%7CJTXM2THZSJHDPEH4IPCBUU%3A20240512%3A9%7CFPP3PVDSUZBVHNEE67AUWV%3A20240512%3A9; auth_session=ih5fycwxzb5qkubabuc7u4qvz3wn2cfjzjdnigdh',
|
||||
// 'x-forwarded-proto': 'https',
|
||||
// 'x-forwarded-host': 'mcnknfld-3000.use2.devtunnels.ms',
|
||||
// 'x-forwarded-for': '10.240.3.64',
|
||||
// 'proxy-connection': 'Keep-Alive',
|
||||
// 'x-middleware-invoke': '',
|
||||
// 'x-invoke-path': '/api/providers/gitlab/callback',
|
||||
// 'x-invoke-query': '%7B%22code%22%3A%22f26181b5c7397444ace5211f9ac4683b2d7bd64cd9431e85d3b6b4722827fabf%22%2C%22__nextDefaultLocale%22%3A%22en%22%2C%22__nextLocale%22%3A%22en%22%7D',
|
||||
// 'x-invoke-output': '/api/providers/gitlab/callback'
|
||||
// }
|
||||
85
apps/dokploy/pages/dashboard/settings/git-providers.tsx
Normal file
85
apps/dokploy/pages/dashboard/settings/git-providers.tsx
Normal file
@@ -0,0 +1,85 @@
|
||||
import { ShowGitProviders } from "@/components/dashboard/settings/git/show-git-providers";
|
||||
import { GitlabSetup } from "@/components/dashboard/settings/github/gitlab-setup";
|
||||
import { ShowDestinations } from "@/components/dashboard/settings/ssh-keys/show-ssh-keys";
|
||||
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 />
|
||||
{/* <ShowDestinations /> */}
|
||||
{/* <GitlabSetup /> */}
|
||||
</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, resolvedUrl } = 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.canAccessToSSHKeys) {
|
||||
return {
|
||||
redirect: {
|
||||
permanent: true,
|
||||
destination: "/",
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
return {
|
||||
props: {
|
||||
trpcState: helpers.dehydrate(),
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
props: {},
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user