Files
dokploy/apps/dokploy/pages/api/providers/gitlab/callback.ts
Mauricio Siu 54bd25da39 feat(gitlab): add optional internal URL for GitLab integration
- Introduced a new field `gitlabInternalUrl` in the GitLab provider settings to allow users to specify an internal URL for OAuth token exchange when GitLab runs on the same instance as Dokploy.
- Updated the GitLab provider forms to include the new field with appropriate descriptions.
- Modified the token exchange logic to utilize the internal URL if provided, enhancing connectivity options for users.
2026-02-07 12:51:45 -06:00

65 lines
1.9 KiB
TypeScript

import { findGitlabById, updateGitlab } from "@dokploy/server";
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);
// Use internal URL for token exchange when GitLab is on same instance as Dokploy
const baseUrl = gitlab.gitlabInternalUrl || gitlab.gitlabUrl;
const gitlabUrl = new URL(baseUrl);
const headers: HeadersInit = {
"Content-Type": "application/x-www-form-urlencoded",
};
// In case of basic auth being present in the URL, we need to remove it from the URL
// and add it to the Authorization header.
if (gitlabUrl.username && gitlabUrl.password) {
headers.Authorization = `Basic ${Buffer.from(`${gitlabUrl.username}:${gitlabUrl.password}`).toString("base64")}`;
}
const url =
gitlabUrl.username && gitlabUrl.password
? new URL(gitlabUrl, {
...gitlabUrl,
username: "",
password: "",
}).toString()
: gitlabUrl.toString();
const response = await fetch(`${url}/oauth/token`, {
method: "POST",
headers,
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");
}