fix: harder to remove destinations and sources

This commit is contained in:
Andras Bacsai
2023-04-03 09:55:13 +02:00
parent cb980fb814
commit 4c8e73ac86
2 changed files with 518 additions and 404 deletions

View File

@@ -1,279 +1,353 @@
import type { FastifyRequest } from 'fastify'; import type { FastifyRequest } from 'fastify';
import { FastifyReply } from 'fastify'; import { FastifyReply } from 'fastify';
import sshConfig from 'ssh-config' import {
import fs from 'fs/promises' errorHandler,
import os from 'os'; executeCommand,
listSettings,
import { createRemoteEngineConfiguration, decrypt, errorHandler, executeCommand, listSettings, prisma, startTraefikProxy, stopTraefikProxy } from '../../../../lib/common'; prisma,
startTraefikProxy,
stopTraefikProxy
} from '../../../../lib/common';
import { checkContainer } from '../../../../lib/docker'; import { checkContainer } from '../../../../lib/docker';
import type { OnlyId } from '../../../../types'; import type { OnlyId } from '../../../../types';
import type { CheckDestination, ListDestinations, NewDestination, Proxy, SaveDestinationSettings } from './types'; import type {
CheckDestination,
ListDestinations,
NewDestination,
Proxy,
SaveDestinationSettings
} from './types';
export async function listDestinations(request: FastifyRequest<ListDestinations>) { export async function listDestinations(request: FastifyRequest<ListDestinations>) {
try { try {
const teamId = request.user.teamId; const teamId = request.user.teamId;
const { onlyVerified = false } = request.query const { onlyVerified = false } = request.query;
let destinations = [] let destinations = [];
if (teamId === '0') { if (teamId === '0') {
destinations = await prisma.destinationDocker.findMany({ include: { teams: true } }); destinations = await prisma.destinationDocker.findMany({ include: { teams: true } });
} else { } else {
destinations = await prisma.destinationDocker.findMany({ destinations = await prisma.destinationDocker.findMany({
where: { teams: { some: { id: teamId } } }, where: { teams: { some: { id: teamId } } },
include: { teams: true } include: { teams: true }
}); });
} }
if (onlyVerified) { if (onlyVerified) {
destinations = destinations.filter(destination => destination.engine || (destination.remoteEngine && destination.remoteVerified)) destinations = destinations.filter(
} (destination) =>
return { destination.engine || (destination.remoteEngine && destination.remoteVerified)
destinations );
} }
} catch ({ status, message }) { return {
return errorHandler({ status, message }) destinations
} };
} catch ({ status, message }) {
return errorHandler({ status, message });
}
} }
export async function checkDestination(request: FastifyRequest<CheckDestination>) { export async function checkDestination(request: FastifyRequest<CheckDestination>) {
try { try {
const { network } = request.body; const { network } = request.body;
const found = await prisma.destinationDocker.findFirst({ where: { network } }); const found = await prisma.destinationDocker.findFirst({ where: { network } });
if (found) { if (found) {
throw { throw {
message: `Network already exists: ${network}` message: `Network already exists: ${network}`
}; };
} }
return {} return {};
} catch ({ status, message }) { } catch ({ status, message }) {
return errorHandler({ status, message }) return errorHandler({ status, message });
} }
} }
export async function getDestination(request: FastifyRequest<OnlyId>) { export async function getDestination(request: FastifyRequest<OnlyId>) {
try { try {
const { id } = request.params const { id } = request.params;
const teamId = request.user?.teamId; const teamId = request.user?.teamId;
const destination = await prisma.destinationDocker.findFirst({ const destination = await prisma.destinationDocker.findFirst({
where: { id, teams: { some: { id: teamId === '0' ? undefined : teamId } } }, where: { id, teams: { some: { id: teamId === '0' ? undefined : teamId } } },
include: { sshKey: true, application: true, service: true, database: true } include: { sshKey: true, application: true, service: true, database: true }
}); });
if (!destination && id !== 'new') { if (!destination && id !== 'new') {
throw { status: 404, message: `Destination not found.` }; throw { status: 404, message: `Destination not found.` };
} }
const settings = await listSettings(); const settings = await listSettings();
const payload = { const payload = {
destination, destination,
settings settings
}; };
return { return {
...payload ...payload
}; };
} catch ({ status, message }) {
} catch ({ status, message }) { return errorHandler({ status, message });
return errorHandler({ status, message }) }
}
} }
export async function newDestination(request: FastifyRequest<NewDestination>, reply: FastifyReply) { export async function newDestination(request: FastifyRequest<NewDestination>, reply: FastifyReply) {
try { try {
const teamId = request.user.teamId; const teamId = request.user.teamId;
const { id } = request.params const { id } = request.params;
let { name, network, engine, isCoolifyProxyUsed, remoteIpAddress, remoteUser, remotePort } = request.body let { name, network, engine, isCoolifyProxyUsed, remoteIpAddress, remoteUser, remotePort } =
if (id === 'new') { request.body;
if (engine) { if (id === 'new') {
const { stdout } = await await executeCommand({ command: `docker network ls --filter 'name=^${network}$' --format '{{json .}}'` }); if (engine) {
if (stdout === '') { const { stdout } = await await executeCommand({
await await executeCommand({ command: `docker network create --attachable ${network}` }); command: `docker network ls --filter 'name=^${network}$' --format '{{json .}}'`
} });
await prisma.destinationDocker.create({ if (stdout === '') {
data: { name, teams: { connect: { id: teamId } }, engine, network, isCoolifyProxyUsed } await await executeCommand({ command: `docker network create --attachable ${network}` });
}); }
const destinations = await prisma.destinationDocker.findMany({ where: { engine } }); await prisma.destinationDocker.create({
const destination = destinations.find((destination) => destination.network === network); data: { name, teams: { connect: { id: teamId } }, engine, network, isCoolifyProxyUsed }
if (destinations.length > 0) { });
const proxyConfigured = destinations.find( const destinations = await prisma.destinationDocker.findMany({ where: { engine } });
(destination) => destination.network !== network && destination.isCoolifyProxyUsed === true const destination = destinations.find((destination) => destination.network === network);
); if (destinations.length > 0) {
if (proxyConfigured) { const proxyConfigured = destinations.find(
isCoolifyProxyUsed = !!proxyConfigured.isCoolifyProxyUsed; (destination) =>
} destination.network !== network && destination.isCoolifyProxyUsed === true
await prisma.destinationDocker.updateMany({ where: { engine }, data: { isCoolifyProxyUsed } }); );
} if (proxyConfigured) {
if (isCoolifyProxyUsed) { isCoolifyProxyUsed = !!proxyConfigured.isCoolifyProxyUsed;
await startTraefikProxy(destination.id); }
} await prisma.destinationDocker.updateMany({
return reply.code(201).send({ id: destination.id }); where: { engine },
} else { data: { isCoolifyProxyUsed }
const destination = await prisma.destinationDocker.create({ });
data: { name, teams: { connect: { id: teamId } }, engine, network, isCoolifyProxyUsed, remoteEngine: true, remoteIpAddress, remoteUser, remotePort: Number(remotePort) } }
}); if (isCoolifyProxyUsed) {
return reply.code(201).send({ id: destination.id }) await startTraefikProxy(destination.id);
} }
} else { return reply.code(201).send({ id: destination.id });
await prisma.destinationDocker.update({ where: { id }, data: { name, engine, network } }); } else {
return reply.code(201).send(); const destination = await prisma.destinationDocker.create({
} data: {
name,
} catch ({ status, message }) { teams: { connect: { id: teamId } },
return errorHandler({ status, message }) engine,
} network,
isCoolifyProxyUsed,
remoteEngine: true,
remoteIpAddress,
remoteUser,
remotePort: Number(remotePort)
}
});
return reply.code(201).send({ id: destination.id });
}
} else {
await prisma.destinationDocker.update({ where: { id }, data: { name, engine, network } });
return reply.code(201).send();
}
} catch ({ status, message }) {
return errorHandler({ status, message });
}
} }
export async function deleteDestination(request: FastifyRequest<OnlyId>) { export async function deleteDestination(request: FastifyRequest<OnlyId>) {
try { try {
const { id } = request.params const { id } = request.params;
const { network, remoteVerified, engine, isCoolifyProxyUsed } = await prisma.destinationDocker.findUnique({ where: { id } }); const appFound = await prisma.application.findFirst({ where: { destinationDockerId: id } });
if (isCoolifyProxyUsed) { const serviceFound = await prisma.service.findFirst({ where: { destinationDockerId: id } });
if (engine || remoteVerified) { const databaseFound = await prisma.database.findFirst({ where: { destinationDockerId: id } });
const { stdout: found } = await executeCommand({ if (appFound || serviceFound || databaseFound) {
dockerId: id, throw {
command: `docker ps -a --filter network=${network} --filter name=coolify-proxy --format '{{.}}'` message: `Destination is in use.<br>Remove all applications, services and databases using this destination first.`
}) };
if (found) { }
await executeCommand({ dockerId: id, command: `docker network disconnect ${network} coolify-proxy` }) const { network, remoteVerified, engine, isCoolifyProxyUsed } =
await executeCommand({ dockerId: id, command: `docker network rm ${network}` }) await prisma.destinationDocker.findUnique({ where: { id } });
} if (isCoolifyProxyUsed) {
} if (engine || remoteVerified) {
} const { stdout: found } = await executeCommand({
await prisma.destinationDocker.delete({ where: { id } }); dockerId: id,
return {} command: `docker ps -a --filter network=${network} --filter name=coolify-proxy --format '{{.}}'`
} catch ({ status, message }) { });
return errorHandler({ status, message }) if (found) {
} await executeCommand({
dockerId: id,
command: `docker network disconnect ${network} coolify-proxy`
});
await executeCommand({ dockerId: id, command: `docker network rm ${network}` });
}
}
}
await prisma.destinationDocker.delete({ where: { id } });
return {};
} catch ({ status, message }) {
return errorHandler({ status, message });
}
} }
export async function saveDestinationSettings(request: FastifyRequest<SaveDestinationSettings>) { export async function saveDestinationSettings(request: FastifyRequest<SaveDestinationSettings>) {
try { try {
const { engine, isCoolifyProxyUsed } = request.body; const { engine, isCoolifyProxyUsed } = request.body;
await prisma.destinationDocker.updateMany({ await prisma.destinationDocker.updateMany({
where: { engine }, where: { engine },
data: { isCoolifyProxyUsed } data: { isCoolifyProxyUsed }
}); });
return { return {
status: 202 status: 202
} };
// return reply.code(201).send(); // return reply.code(201).send();
} catch ({ status, message }) { } catch ({ status, message }) {
return errorHandler({ status, message }) return errorHandler({ status, message });
} }
} }
export async function startProxy(request: FastifyRequest<Proxy>) { export async function startProxy(request: FastifyRequest<Proxy>) {
const { id } = request.params const { id } = request.params;
try { try {
await startTraefikProxy(id); await startTraefikProxy(id);
return {} return {};
} catch ({ status, message }) { } catch ({ status, message }) {
await stopTraefikProxy(id); await stopTraefikProxy(id);
return errorHandler({ status, message }) return errorHandler({ status, message });
} }
} }
export async function stopProxy(request: FastifyRequest<Proxy>) { export async function stopProxy(request: FastifyRequest<Proxy>) {
const { id } = request.params const { id } = request.params;
try { try {
await stopTraefikProxy(id); await stopTraefikProxy(id);
return {} return {};
} catch ({ status, message }) { } catch ({ status, message }) {
return errorHandler({ status, message }) return errorHandler({ status, message });
} }
} }
export async function restartProxy(request: FastifyRequest<Proxy>) { export async function restartProxy(request: FastifyRequest<Proxy>) {
const { id } = request.params const { id } = request.params;
try { try {
await stopTraefikProxy(id); await stopTraefikProxy(id);
await startTraefikProxy(id); await startTraefikProxy(id);
await prisma.destinationDocker.update({ await prisma.destinationDocker.update({
where: { id }, where: { id },
data: { isCoolifyProxyUsed: true } data: { isCoolifyProxyUsed: true }
}); });
return {} return {};
} catch ({ status, message }) { } catch ({ status, message }) {
await prisma.destinationDocker.update({ await prisma.destinationDocker.update({
where: { id }, where: { id },
data: { isCoolifyProxyUsed: false } data: { isCoolifyProxyUsed: false }
}); });
return errorHandler({ status, message }) return errorHandler({ status, message });
} }
} }
export async function assignSSHKey(request: FastifyRequest) { export async function assignSSHKey(request: FastifyRequest) {
try { try {
const { id: sshKeyId } = request.body; const { id: sshKeyId } = request.body;
const { id } = request.params; const { id } = request.params;
await prisma.destinationDocker.update({ where: { id }, data: { sshKey: { connect: { id: sshKeyId } } } }) await prisma.destinationDocker.update({
return {} where: { id },
} catch ({ status, message }) { data: { sshKey: { connect: { id: sshKeyId } } }
return errorHandler({ status, message }) });
} return {};
} catch ({ status, message }) {
return errorHandler({ status, message });
}
} }
export async function verifyRemoteDockerEngineFn(id: string) { export async function verifyRemoteDockerEngineFn(id: string) {
const { remoteIpAddress, network, isCoolifyProxyUsed } = await prisma.destinationDocker.findFirst({ where: { id } }) const { remoteIpAddress, network, isCoolifyProxyUsed } = await prisma.destinationDocker.findFirst(
const daemonJson = `daemon-${id}.json` { where: { id } }
try { );
await executeCommand({ sshCommand: true, command: `docker network inspect ${network}`, dockerId: id }); const daemonJson = `daemon-${id}.json`;
} catch (error) { try {
await executeCommand({ command: `docker network create --attachable ${network}`, dockerId: id }); await executeCommand({
} sshCommand: true,
command: `docker network inspect ${network}`,
dockerId: id
});
} catch (error) {
await executeCommand({
command: `docker network create --attachable ${network}`,
dockerId: id
});
}
try { try {
await executeCommand({ sshCommand: true, command: `docker network inspect coolify-infra`, dockerId: id }); await executeCommand({
} catch (error) { sshCommand: true,
await executeCommand({ command: `docker network create --attachable coolify-infra`, dockerId: id }); command: `docker network inspect coolify-infra`,
} dockerId: id
});
} catch (error) {
await executeCommand({
command: `docker network create --attachable coolify-infra`,
dockerId: id
});
}
if (isCoolifyProxyUsed) await startTraefikProxy(id); if (isCoolifyProxyUsed) await startTraefikProxy(id);
let isUpdated = false; let isUpdated = false;
let daemonJsonParsed = { let daemonJsonParsed = {
"live-restore": true, 'live-restore': true,
"features": { features: {
"buildkit": true buildkit: true
} }
}; };
try { try {
const { stdout: daemonJson } = await executeCommand({ sshCommand: true, dockerId: id, command: `cat /etc/docker/daemon.json` }); const { stdout: daemonJson } = await executeCommand({
daemonJsonParsed = JSON.parse(daemonJson); sshCommand: true,
if (!daemonJsonParsed['live-restore'] || daemonJsonParsed['live-restore'] !== true) { dockerId: id,
isUpdated = true; command: `cat /etc/docker/daemon.json`
daemonJsonParsed['live-restore'] = true });
daemonJsonParsed = JSON.parse(daemonJson);
} if (!daemonJsonParsed['live-restore'] || daemonJsonParsed['live-restore'] !== true) {
if (!daemonJsonParsed?.features?.buildkit) { isUpdated = true;
isUpdated = true; daemonJsonParsed['live-restore'] = true;
daemonJsonParsed.features = { }
buildkit: true if (!daemonJsonParsed?.features?.buildkit) {
} isUpdated = true;
} daemonJsonParsed.features = {
} catch (error) { buildkit: true
isUpdated = true; };
} }
try { } catch (error) {
if (isUpdated) { isUpdated = true;
await executeCommand({ shell: true, command: `echo '${JSON.stringify(daemonJsonParsed, null, 2)}' > /tmp/${daemonJson}` }) }
await executeCommand({ dockerId: id, command: `scp /tmp/${daemonJson} ${remoteIpAddress}-remote:/etc/docker/daemon.json` }); try {
await executeCommand({ command: `rm /tmp/${daemonJson}` }) if (isUpdated) {
await executeCommand({ sshCommand: true, dockerId: id, command: `systemctl restart docker` }); await executeCommand({
} shell: true,
await prisma.destinationDocker.update({ where: { id }, data: { remoteVerified: true } }) command: `echo '${JSON.stringify(daemonJsonParsed, null, 2)}' > /tmp/${daemonJson}`
} catch (error) { });
throw new Error('Error while verifying remote docker engine') await executeCommand({
} dockerId: id,
command: `scp /tmp/${daemonJson} ${remoteIpAddress}-remote:/etc/docker/daemon.json`
});
await executeCommand({ command: `rm /tmp/${daemonJson}` });
await executeCommand({ sshCommand: true, dockerId: id, command: `systemctl restart docker` });
}
await prisma.destinationDocker.update({ where: { id }, data: { remoteVerified: true } });
} catch (error) {
throw new Error('Error while verifying remote docker engine');
}
} }
export async function verifyRemoteDockerEngine(request: FastifyRequest<OnlyId>, reply: FastifyReply) { export async function verifyRemoteDockerEngine(
const { id } = request.params; request: FastifyRequest<OnlyId>,
try { reply: FastifyReply
await verifyRemoteDockerEngineFn(id); ) {
return reply.code(201).send() const { id } = request.params;
} catch ({ status, message }) { try {
await prisma.destinationDocker.update({ where: { id }, data: { remoteVerified: false } }) await verifyRemoteDockerEngineFn(id);
return errorHandler({ status, message }) return reply.code(201).send();
} } catch ({ status, message }) {
await prisma.destinationDocker.update({ where: { id }, data: { remoteVerified: false } });
return errorHandler({ status, message });
}
} }
export async function getDestinationStatus(request: FastifyRequest<OnlyId>) { export async function getDestinationStatus(request: FastifyRequest<OnlyId>) {
try { try {
const { id } = request.params const { id } = request.params;
const destination = await prisma.destinationDocker.findUnique({ where: { id } }) const destination = await prisma.destinationDocker.findUnique({ where: { id } });
const { found: isRunning } = await checkContainer({ dockerId: destination.id, container: 'coolify-proxy', remove: true }) const { found: isRunning } = await checkContainer({
return { dockerId: destination.id,
isRunning container: 'coolify-proxy',
} remove: true
} catch ({ status, message }) { });
return errorHandler({ status, message }) return {
} isRunning
};
} catch ({ status, message }) {
return errorHandler({ status, message });
}
} }

View File

@@ -1,191 +1,231 @@
import cuid from 'cuid'; import cuid from 'cuid';
import type { FastifyRequest } from 'fastify'; import type { FastifyRequest } from 'fastify';
import { FastifyReply } from 'fastify';
import { decrypt, encrypt, errorHandler, prisma } from '../../../../lib/common'; import { decrypt, encrypt, errorHandler, prisma } from '../../../../lib/common';
import { OnlyId } from '../../../../types'; import { OnlyId } from '../../../../types';
import { CheckGitLabOAuthId, SaveGitHubSource, SaveGitLabSource } from './types'; import { CheckGitLabOAuthId, SaveGitHubSource, SaveGitLabSource } from './types';
export async function listSources(request: FastifyRequest) { export async function listSources(request: FastifyRequest) {
try { try {
const teamId = request.user?.teamId; const teamId = request.user?.teamId;
const sources = await prisma.gitSource.findMany({ const sources = await prisma.gitSource.findMany({
where: { OR: [{ teams: { some: { id: teamId === "0" ? undefined : teamId } } }, { isSystemWide: true }] }, where: {
include: { teams: true, githubApp: true, gitlabApp: true } OR: [
}); { teams: { some: { id: teamId === '0' ? undefined : teamId } } },
return { { isSystemWide: true }
sources ]
} },
} catch ({ status, message }) { include: { teams: true, githubApp: true, gitlabApp: true }
return errorHandler({ status, message }) });
} return {
sources
};
} catch ({ status, message }) {
return errorHandler({ status, message });
}
} }
export async function saveSource(request, reply) { export async function saveSource(request, reply) {
try { try {
const { id } = request.params const { id } = request.params;
let { name, htmlUrl, apiUrl, customPort, customUser, isSystemWide } = request.body let { name, htmlUrl, apiUrl, customPort, customUser, isSystemWide } = request.body;
if (customPort) customPort = Number(customPort) if (customPort) customPort = Number(customPort);
await prisma.gitSource.update({ await prisma.gitSource.update({
where: { id }, where: { id },
data: { name, htmlUrl, apiUrl, customPort, customUser, isSystemWide } data: { name, htmlUrl, apiUrl, customPort, customUser, isSystemWide }
}); });
return reply.code(201).send() return reply.code(201).send();
} catch ({ status, message }) { } catch ({ status, message }) {
return errorHandler({ status, message }) return errorHandler({ status, message });
} }
} }
export async function getSource(request: FastifyRequest<OnlyId>) { export async function getSource(request: FastifyRequest<OnlyId>) {
try { try {
const { id } = request.params const { id } = request.params;
const { teamId } = request.user const { teamId } = request.user;
const settings = await prisma.setting.findFirst({}); const settings = await prisma.setting.findFirst({});
if (id === 'new') { if (id === 'new') {
return { return {
source: { source: {
name: null, name: null,
type: null, type: null,
htmlUrl: null, htmlUrl: null,
apiUrl: null, apiUrl: null,
organization: null, organization: null,
customPort: 22, customPort: 22,
customUser: 'git', customUser: 'git'
}, },
settings settings
} };
} }
const source = await prisma.gitSource.findFirst({ const source = await prisma.gitSource.findFirst({
where: { id, OR: [{ teams: { some: { id: teamId === "0" ? undefined : teamId } } }, { isSystemWide: true }] }, where: {
include: { githubApp: true, gitlabApp: true } id,
}); OR: [
if (!source) { { teams: { some: { id: teamId === '0' ? undefined : teamId } } },
throw { status: 404, message: 'Source not found.' } { isSystemWide: true }
} ]
},
include: { githubApp: true, gitlabApp: true }
});
if (!source) {
throw { status: 404, message: 'Source not found.' };
}
if (source?.githubApp?.clientSecret) if (source?.githubApp?.clientSecret)
source.githubApp.clientSecret = decrypt(source.githubApp.clientSecret); source.githubApp.clientSecret = decrypt(source.githubApp.clientSecret);
if (source?.githubApp?.webhookSecret) if (source?.githubApp?.webhookSecret)
source.githubApp.webhookSecret = decrypt(source.githubApp.webhookSecret); source.githubApp.webhookSecret = decrypt(source.githubApp.webhookSecret);
if (source?.githubApp?.privateKey) source.githubApp.privateKey = decrypt(source.githubApp.privateKey); if (source?.githubApp?.privateKey)
if (source?.gitlabApp?.appSecret) source.gitlabApp.appSecret = decrypt(source.gitlabApp.appSecret); source.githubApp.privateKey = decrypt(source.githubApp.privateKey);
if (source?.gitlabApp?.appSecret)
source.gitlabApp.appSecret = decrypt(source.gitlabApp.appSecret);
return { return {
source, source,
settings settings
}; };
} catch ({ status, message }) {
} catch ({ status, message }) { return errorHandler({ status, message });
return errorHandler({ status, message }) }
}
} }
export async function deleteSource(request) { export async function deleteSource(request) {
try { try {
const { id } = request.params const { id } = request.params;
const source = await prisma.gitSource.delete({ const gitAppFound = await prisma.application.findFirst({ where: { gitSourceId: id } });
where: { id }, if (gitAppFound) {
include: { githubApp: true, gitlabApp: true } throw {
}); status: 400,
if (source.githubAppId) { message: 'This source is used by an application. Please remove the application first.'
await prisma.githubApp.delete({ where: { id: source.githubAppId } }); };
} }
if (source.gitlabAppId) { const source = await prisma.gitSource.delete({
await prisma.gitlabApp.delete({ where: { id: source.gitlabAppId } }); where: { id },
} include: { githubApp: true, gitlabApp: true }
return {} });
} catch ({ status, message }) { if (source.githubAppId) {
return errorHandler({ status, message }) await prisma.githubApp.delete({ where: { id: source.githubAppId } });
} }
if (source.gitlabAppId) {
await prisma.gitlabApp.delete({ where: { id: source.gitlabAppId } });
}
return {};
} catch ({ status, message }) {
return errorHandler({ status, message });
}
} }
export async function saveGitHubSource(request: FastifyRequest<SaveGitHubSource>) { export async function saveGitHubSource(request: FastifyRequest<SaveGitHubSource>) {
try { try {
const { teamId } = request.user const { teamId } = request.user;
const { id } = request.params const { id } = request.params;
let { name, htmlUrl, apiUrl, organization, customPort, isSystemWide } = request.body let { name, htmlUrl, apiUrl, organization, customPort, isSystemWide } = request.body;
if (customPort) customPort = Number(customPort) if (customPort) customPort = Number(customPort);
if (id === 'new') { if (id === 'new') {
const newId = cuid() const newId = cuid();
await prisma.gitSource.create({ await prisma.gitSource.create({
data: { data: {
id: newId, id: newId,
name, name,
htmlUrl, htmlUrl,
apiUrl, apiUrl,
organization, organization,
customPort, customPort,
isSystemWide, isSystemWide,
type: 'github', type: 'github',
teams: { connect: { id: teamId } } teams: { connect: { id: teamId } }
} }
}); });
return { return {
id: newId id: newId
} };
} }
throw { status: 500, message: 'Wrong request.' } throw { status: 500, message: 'Wrong request.' };
} catch ({ status, message }) { } catch ({ status, message }) {
return errorHandler({ status, message }) return errorHandler({ status, message });
} }
} }
export async function saveGitLabSource(request: FastifyRequest<SaveGitLabSource>) { export async function saveGitLabSource(request: FastifyRequest<SaveGitLabSource>) {
try { try {
const { id } = request.params const { id } = request.params;
const { teamId } = request.user const { teamId } = request.user;
let { type, name, htmlUrl, apiUrl, oauthId, appId, appSecret, groupName, customPort, customUser } = let {
request.body type,
name,
htmlUrl,
apiUrl,
oauthId,
appId,
appSecret,
groupName,
customPort,
customUser
} = request.body;
if (oauthId) oauthId = Number(oauthId); if (oauthId) oauthId = Number(oauthId);
if (customPort) customPort = Number(customPort) if (customPort) customPort = Number(customPort);
const encryptedAppSecret = encrypt(appSecret); const encryptedAppSecret = encrypt(appSecret);
if (id === 'new') { if (id === 'new') {
const newId = cuid() const newId = cuid();
await prisma.gitSource.create({ data: { id: newId, type, apiUrl, htmlUrl, name, customPort, customUser, teams: { connect: { id: teamId } } } }); await prisma.gitSource.create({
await prisma.gitlabApp.create({ data: {
data: { id: newId,
teams: { connect: { id: teamId } }, type,
appId, apiUrl,
oauthId, htmlUrl,
groupName, name,
appSecret: encryptedAppSecret, customPort,
gitSource: { connect: { id: newId } } customUser,
} teams: { connect: { id: teamId } }
}); }
return { });
status: 201, await prisma.gitlabApp.create({
id: newId data: {
} teams: { connect: { id: teamId } },
} else { appId,
await prisma.gitSource.update({ where: { id }, data: { type, apiUrl, htmlUrl, name, customPort, customUser } }); oauthId,
await prisma.gitlabApp.update({ groupName,
where: { id }, appSecret: encryptedAppSecret,
data: { gitSource: { connect: { id: newId } }
appId, }
oauthId, });
groupName, return {
appSecret: encryptedAppSecret, status: 201,
} id: newId
}); };
} } else {
return { status: 201 }; await prisma.gitSource.update({
where: { id },
} catch ({ status, message }) { data: { type, apiUrl, htmlUrl, name, customPort, customUser }
return errorHandler({ status, message }) });
} await prisma.gitlabApp.update({
where: { id },
data: {
appId,
oauthId,
groupName,
appSecret: encryptedAppSecret
}
});
}
return { status: 201 };
} catch ({ status, message }) {
return errorHandler({ status, message });
}
} }
export async function checkGitLabOAuthID(request: FastifyRequest<CheckGitLabOAuthId>) { export async function checkGitLabOAuthID(request: FastifyRequest<CheckGitLabOAuthId>) {
try { try {
const { oauthId } = request.body const { oauthId } = request.body;
const found = await prisma.gitlabApp.findFirst({ where: { oauthId: Number(oauthId) } }); const found = await prisma.gitlabApp.findFirst({ where: { oauthId: Number(oauthId) } });
if (found) { if (found) {
throw { status: 500, message: 'OAuthID already configured in Coolify.' } throw { status: 500, message: 'OAuthID already configured in Coolify.' };
} }
return {} return {};
} catch ({ status, message }) { } catch ({ status, message }) {
return errorHandler({ status, message }) return errorHandler({ status, message });
} }
} }