mirror of
https://github.com/ershisan99/coolify.git
synced 2025-12-17 12:33:06 +00:00
wip
This commit is contained in:
@@ -26,8 +26,6 @@
|
|||||||
"@iarna/toml": "2.2.5",
|
"@iarna/toml": "2.2.5",
|
||||||
"@ladjs/graceful": "3.2.1",
|
"@ladjs/graceful": "3.2.1",
|
||||||
"@prisma/client": "4.8.1",
|
"@prisma/client": "4.8.1",
|
||||||
"@sentry/node": "7.30.0",
|
|
||||||
"@sentry/tracing": "7.30.0",
|
|
||||||
"axe": "11.2.1",
|
"axe": "11.2.1",
|
||||||
"bcryptjs": "2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
"bree": "9.1.3",
|
"bree": "9.1.3",
|
||||||
|
|||||||
@@ -102,14 +102,17 @@ async function reEncryptSecrets() {
|
|||||||
}
|
}
|
||||||
if (secretOld !== secretNew) {
|
if (secretOld !== secretNew) {
|
||||||
console.log('secrets are different, so re-encrypting');
|
console.log('secrets are different, so re-encrypting');
|
||||||
// const secrets = await prisma.secret.findMany();
|
const secrets = await prisma.secret.findMany();
|
||||||
// if (secrets.length > 0) {
|
if (secrets.length > 0) {
|
||||||
// for (const secret of secrets) {
|
for (const secret of secrets) {
|
||||||
// const value = decrypt(secret.value, secretOld);
|
const value = decrypt(secret.value, secretOld);
|
||||||
// const newValue = encrypt(value, secretNew);
|
const newValue = encrypt(value, secretNew);
|
||||||
// console.log({ value: secret.value, newValue });
|
await prisma.secret.update({
|
||||||
// }
|
where: { id: secret.id },
|
||||||
// }
|
data: { value: newValue }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
main()
|
main()
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import {
|
|||||||
isDev,
|
isDev,
|
||||||
listSettings,
|
listSettings,
|
||||||
prisma,
|
prisma,
|
||||||
sentryDSN,
|
|
||||||
startTraefikProxy,
|
startTraefikProxy,
|
||||||
startTraefikTCPProxy,
|
startTraefikTCPProxy,
|
||||||
version
|
version
|
||||||
@@ -32,7 +31,6 @@ import { verifyRemoteDockerEngineFn } from './routes/api/v1/destinations/handler
|
|||||||
import { checkContainer } from './lib/docker';
|
import { checkContainer } from './lib/docker';
|
||||||
import { migrateApplicationPersistentStorage, migrateServicesToNewTemplate } from './lib';
|
import { migrateApplicationPersistentStorage, migrateServicesToNewTemplate } from './lib';
|
||||||
import { refreshTags, refreshTemplates } from './routes/api/v1/handlers';
|
import { refreshTags, refreshTemplates } from './routes/api/v1/handlers';
|
||||||
import * as Sentry from '@sentry/node';
|
|
||||||
declare module 'fastify' {
|
declare module 'fastify' {
|
||||||
interface FastifyInstance {
|
interface FastifyInstance {
|
||||||
config: {
|
config: {
|
||||||
@@ -281,9 +279,6 @@ async function initServer() {
|
|||||||
if (settings.doNotTrack === true) {
|
if (settings.doNotTrack === true) {
|
||||||
console.log('[000] Telemetry disabled...');
|
console.log('[000] Telemetry disabled...');
|
||||||
} else {
|
} else {
|
||||||
if (settings.sentryDSN !== sentryDSN) {
|
|
||||||
await prisma.setting.update({ where: { id: '0' }, data: { sentryDSN } });
|
|
||||||
}
|
|
||||||
// Initialize Sentry
|
// Initialize Sentry
|
||||||
// Sentry.init({
|
// Sentry.init({
|
||||||
// dsn: sentryDSN,
|
// dsn: sentryDSN,
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import type { Config } from 'unique-names-generator';
|
|||||||
import generator from 'generate-password';
|
import generator from 'generate-password';
|
||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
import { promises as dns } from 'dns';
|
import { promises as dns } from 'dns';
|
||||||
import * as Sentry from '@sentry/node';
|
|
||||||
import { PrismaClient } from '@prisma/client';
|
import { PrismaClient } from '@prisma/client';
|
||||||
import os from 'os';
|
import os from 'os';
|
||||||
import * as SSHConfig from 'ssh-config/src/ssh-config';
|
import * as SSHConfig from 'ssh-config/src/ssh-config';
|
||||||
@@ -23,8 +22,7 @@ export const version = '3.12.33';
|
|||||||
export const isDev = process.env.NODE_ENV === 'development';
|
export const isDev = process.env.NODE_ENV === 'development';
|
||||||
export const proxyPort = process.env.COOLIFY_PROXY_PORT;
|
export const proxyPort = process.env.COOLIFY_PROXY_PORT;
|
||||||
export const proxySecurePort = process.env.COOLIFY_PROXY_SECURE_PORT;
|
export const proxySecurePort = process.env.COOLIFY_PROXY_SECURE_PORT;
|
||||||
export const sentryDSN =
|
|
||||||
'https://409f09bcb7af47928d3e0f46b78987f3@o1082494.ingest.sentry.io/4504236622217216';
|
|
||||||
const algorithm = 'aes-256-ctr';
|
const algorithm = 'aes-256-ctr';
|
||||||
const customConfig: Config = {
|
const customConfig: Config = {
|
||||||
dictionaries: [adjectives, colors, animals],
|
dictionaries: [adjectives, colors, animals],
|
||||||
@@ -1685,9 +1683,6 @@ export function errorHandler({
|
|||||||
if (message.includes('Unique constraint failed')) {
|
if (message.includes('Unique constraint failed')) {
|
||||||
message = 'This data is unique and already exists. Please try again with a different value.';
|
message = 'This data is unique and already exists. Please try again with a different value.';
|
||||||
}
|
}
|
||||||
if (type === 'normal') {
|
|
||||||
Sentry.captureException(message);
|
|
||||||
}
|
|
||||||
throw { status, message };
|
throw { status, message };
|
||||||
}
|
}
|
||||||
export async function generateSshKeyPair(): Promise<{ publicKey: string; privateKey: string }> {
|
export async function generateSshKeyPair(): Promise<{ publicKey: string; privateKey: string }> {
|
||||||
|
|||||||
@@ -13,8 +13,12 @@ declare module '@fastify/jwt' {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default fp<FastifyJWTOptions>(async (fastify, opts) => {
|
export default fp<FastifyJWTOptions>(async (fastify, opts) => {
|
||||||
|
let secretKey = fastify.config.COOLIFY_SECRET_KEY_BETTER;
|
||||||
|
if (!secretKey) {
|
||||||
|
secretKey = fastify.config.COOLIFY_SECRET_KEY;
|
||||||
|
}
|
||||||
fastify.register(fastifyJwt, {
|
fastify.register(fastifyJwt, {
|
||||||
secret: fastify.config.COOLIFY_SECRET_KEY_BETTER ?? fastify.config.COOLIFY_SECRET_KEY
|
secret: secretKey
|
||||||
});
|
});
|
||||||
|
|
||||||
fastify.decorate('authenticate', async function (request, reply) {
|
fastify.decorate('authenticate', async function (request, reply) {
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import {
|
|||||||
prisma,
|
prisma,
|
||||||
uniqueName,
|
uniqueName,
|
||||||
version,
|
version,
|
||||||
sentryDSN,
|
|
||||||
executeCommand
|
executeCommand
|
||||||
} from '../../../lib/common';
|
} from '../../../lib/common';
|
||||||
import { scheduler } from '../../../lib/scheduler';
|
import { scheduler } from '../../../lib/scheduler';
|
||||||
@@ -452,7 +451,6 @@ export async function getCurrentUser(request: FastifyRequest<GetCurrentUser>, fa
|
|||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
settings: await prisma.setting.findUnique({ where: { id: '0' } }),
|
settings: await prisma.setting.findUnique({ where: { id: '0' } }),
|
||||||
sentryDSN,
|
|
||||||
pendingInvitations,
|
pendingInvitations,
|
||||||
token,
|
token,
|
||||||
...request.user
|
...request.user
|
||||||
|
|||||||
@@ -1,34 +1,65 @@
|
|||||||
import { promises as dns } from 'dns';
|
import { promises as dns } from 'dns';
|
||||||
import { X509Certificate } from 'node:crypto';
|
import { X509Certificate } from 'node:crypto';
|
||||||
import * as Sentry from '@sentry/node';
|
|
||||||
import type { FastifyReply, FastifyRequest } from 'fastify';
|
import type { FastifyReply, FastifyRequest } from 'fastify';
|
||||||
import { checkDomainsIsValidInDNS, decrypt, encrypt, errorHandler, executeCommand, getDomain, isDev, isDNSValid, isDomainConfigured, listSettings, prisma, sentryDSN, version } from '../../../../lib/common';
|
import {
|
||||||
import { AddDefaultRegistry, CheckDNS, CheckDomain, DeleteDomain, OnlyIdInBody, SaveSettings, SaveSSHKey, SetDefaultRegistry } from './types';
|
checkDomainsIsValidInDNS,
|
||||||
|
decrypt,
|
||||||
|
encrypt,
|
||||||
|
errorHandler,
|
||||||
|
executeCommand,
|
||||||
|
getDomain,
|
||||||
|
isDev,
|
||||||
|
isDNSValid,
|
||||||
|
isDomainConfigured,
|
||||||
|
listSettings,
|
||||||
|
prisma
|
||||||
|
} from '../../../../lib/common';
|
||||||
|
import {
|
||||||
|
AddDefaultRegistry,
|
||||||
|
CheckDNS,
|
||||||
|
CheckDomain,
|
||||||
|
DeleteDomain,
|
||||||
|
OnlyIdInBody,
|
||||||
|
SaveSettings,
|
||||||
|
SaveSSHKey,
|
||||||
|
SetDefaultRegistry
|
||||||
|
} from './types';
|
||||||
|
|
||||||
export async function listAllSettings(request: FastifyRequest) {
|
export async function listAllSettings(request: FastifyRequest) {
|
||||||
try {
|
try {
|
||||||
const teamId = request.user.teamId;
|
const teamId = request.user.teamId;
|
||||||
const settings = await listSettings();
|
const settings = await listSettings();
|
||||||
const sshKeys = await prisma.sshKey.findMany({ where: { team: { id: teamId } } })
|
const sshKeys = await prisma.sshKey.findMany({ where: { team: { id: teamId } } });
|
||||||
let registries = await prisma.dockerRegistry.findMany({ where: { team: { id: teamId } } })
|
let registries = await prisma.dockerRegistry.findMany({ where: { team: { id: teamId } } });
|
||||||
registries = registries.map((registry) => {
|
registries = registries.map((registry) => {
|
||||||
if (registry.password) {
|
if (registry.password) {
|
||||||
registry.password = decrypt(registry.password)
|
registry.password = decrypt(registry.password);
|
||||||
}
|
}
|
||||||
return registry
|
return registry;
|
||||||
})
|
});
|
||||||
const unencryptedKeys = []
|
const unencryptedKeys = [];
|
||||||
if (sshKeys.length > 0) {
|
if (sshKeys.length > 0) {
|
||||||
for (const key of sshKeys) {
|
for (const key of sshKeys) {
|
||||||
unencryptedKeys.push({ id: key.id, name: key.name, privateKey: decrypt(key.privateKey), createdAt: key.createdAt })
|
unencryptedKeys.push({
|
||||||
|
id: key.id,
|
||||||
|
name: key.name,
|
||||||
|
privateKey: decrypt(key.privateKey),
|
||||||
|
createdAt: key.createdAt
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const certificates = await prisma.certificate.findMany({ where: { team: { id: teamId } } })
|
const certificates = await prisma.certificate.findMany({ where: { team: { id: teamId } } });
|
||||||
let cns = [];
|
let cns = [];
|
||||||
for (const certificate of certificates) {
|
for (const certificate of certificates) {
|
||||||
const x509 = new X509Certificate(certificate.cert);
|
const x509 = new X509Certificate(certificate.cert);
|
||||||
cns.push({ commonName: x509.subject.split('\n').find((s) => s.startsWith('CN=')).replace('CN=', ''), id: certificate.id, createdAt: certificate.createdAt })
|
cns.push({
|
||||||
|
commonName: x509.subject
|
||||||
|
.split('\n')
|
||||||
|
.find((s) => s.startsWith('CN='))
|
||||||
|
.replace('CN=', ''),
|
||||||
|
id: certificate.id,
|
||||||
|
createdAt: certificate.createdAt
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -36,9 +67,9 @@ export async function listAllSettings(request: FastifyRequest) {
|
|||||||
certificates: cns,
|
certificates: cns,
|
||||||
sshKeys: unencryptedKeys,
|
sshKeys: unencryptedKeys,
|
||||||
registries
|
registries
|
||||||
}
|
};
|
||||||
} catch ({ status, message }) {
|
} catch ({ status, message }) {
|
||||||
return errorHandler({ status, message })
|
return errorHandler({ status, message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export async function saveSettings(request: FastifyRequest<SaveSettings>, reply: FastifyReply) {
|
export async function saveSettings(request: FastifyRequest<SaveSettings>, reply: FastifyReply) {
|
||||||
@@ -57,30 +88,48 @@ export async function saveSettings(request: FastifyRequest<SaveSettings>, reply:
|
|||||||
isDNSCheckEnabled,
|
isDNSCheckEnabled,
|
||||||
DNSServers,
|
DNSServers,
|
||||||
proxyDefaultRedirect
|
proxyDefaultRedirect
|
||||||
} = request.body
|
} = request.body;
|
||||||
const { id, previewSeparator: SetPreviewSeparator } = await listSettings();
|
const { id, previewSeparator: SetPreviewSeparator } = await listSettings();
|
||||||
if (numberOfDockerImagesKeptLocally) {
|
if (numberOfDockerImagesKeptLocally) {
|
||||||
numberOfDockerImagesKeptLocally = Number(numberOfDockerImagesKeptLocally)
|
numberOfDockerImagesKeptLocally = Number(numberOfDockerImagesKeptLocally);
|
||||||
}
|
}
|
||||||
if (previewSeparator == '') {
|
if (previewSeparator == '') {
|
||||||
previewSeparator = '.'
|
previewSeparator = '.';
|
||||||
}
|
}
|
||||||
if (SetPreviewSeparator != previewSeparator) {
|
if (SetPreviewSeparator != previewSeparator) {
|
||||||
const applications = await prisma.application.findMany({ where: { previewApplication: { some: { id: { not: undefined } } } }, include: { previewApplication: true } })
|
const applications = await prisma.application.findMany({
|
||||||
|
where: { previewApplication: { some: { id: { not: undefined } } } },
|
||||||
|
include: { previewApplication: true }
|
||||||
|
});
|
||||||
for (const application of applications) {
|
for (const application of applications) {
|
||||||
for (const preview of application.previewApplication) {
|
for (const preview of application.previewApplication) {
|
||||||
const { protocol } = new URL(preview.customDomain)
|
const { protocol } = new URL(preview.customDomain);
|
||||||
const { pullmergeRequestId } = preview
|
const { pullmergeRequestId } = preview;
|
||||||
const { fqdn } = application
|
const { fqdn } = application;
|
||||||
const newPreviewDomain = `${protocol}//${pullmergeRequestId}${previewSeparator}${getDomain(fqdn)}`
|
const newPreviewDomain = `${protocol}//${pullmergeRequestId}${previewSeparator}${getDomain(
|
||||||
await prisma.previewApplication.update({ where: { id: preview.id }, data: { customDomain: newPreviewDomain } })
|
fqdn
|
||||||
|
)}`;
|
||||||
|
await prisma.previewApplication.update({
|
||||||
|
where: { id: preview.id },
|
||||||
|
data: { customDomain: newPreviewDomain }
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await prisma.setting.update({
|
await prisma.setting.update({
|
||||||
where: { id },
|
where: { id },
|
||||||
data: { previewSeparator, numberOfDockerImagesKeptLocally, doNotTrack, isRegistrationEnabled, dualCerts, isAutoUpdateEnabled, isDNSCheckEnabled, DNSServers, isAPIDebuggingEnabled }
|
data: {
|
||||||
|
previewSeparator,
|
||||||
|
numberOfDockerImagesKeptLocally,
|
||||||
|
doNotTrack,
|
||||||
|
isRegistrationEnabled,
|
||||||
|
dualCerts,
|
||||||
|
isAutoUpdateEnabled,
|
||||||
|
isDNSCheckEnabled,
|
||||||
|
DNSServers,
|
||||||
|
isAPIDebuggingEnabled
|
||||||
|
}
|
||||||
});
|
});
|
||||||
if (fqdn) {
|
if (fqdn) {
|
||||||
await prisma.setting.update({ where: { id }, data: { fqdn } });
|
await prisma.setting.update({ where: { id }, data: { fqdn } });
|
||||||
@@ -97,14 +146,14 @@ export async function saveSettings(request: FastifyRequest<SaveSettings>, reply:
|
|||||||
// });
|
// });
|
||||||
// console.log('Sentry initialized')
|
// console.log('Sentry initialized')
|
||||||
}
|
}
|
||||||
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 deleteDomain(request: FastifyRequest<DeleteDomain>, reply: FastifyReply) {
|
export async function deleteDomain(request: FastifyRequest<DeleteDomain>, reply: FastifyReply) {
|
||||||
try {
|
try {
|
||||||
const { fqdn } = request.body
|
const { fqdn } = request.body;
|
||||||
const { DNSServers } = await listSettings();
|
const { DNSServers } = await listSettings();
|
||||||
if (DNSServers) {
|
if (DNSServers) {
|
||||||
dns.setServers([...DNSServers.split(',')]);
|
dns.setServers([...DNSServers.split(',')]);
|
||||||
@@ -116,37 +165,37 @@ export async function deleteDomain(request: FastifyRequest<DeleteDomain>, reply:
|
|||||||
// Do not care.
|
// Do not care.
|
||||||
}
|
}
|
||||||
await prisma.setting.update({ where: { fqdn }, data: { fqdn: null } });
|
await prisma.setting.update({ where: { fqdn }, data: { fqdn: null } });
|
||||||
return reply.redirect(302, ip ? `http://${ip[0]}:3000/settings` : undefined)
|
return reply.redirect(302, ip ? `http://${ip[0]}:3000/settings` : undefined);
|
||||||
} catch ({ status, message }) {
|
} catch ({ status, message }) {
|
||||||
return errorHandler({ status, message })
|
return errorHandler({ status, message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function checkDomain(request: FastifyRequest<CheckDomain>) {
|
export async function checkDomain(request: FastifyRequest<CheckDomain>) {
|
||||||
try {
|
try {
|
||||||
const { id } = request.params;
|
const { id } = request.params;
|
||||||
let { fqdn, forceSave, dualCerts, isDNSCheckEnabled } = request.body
|
let { fqdn, forceSave, dualCerts, isDNSCheckEnabled } = request.body;
|
||||||
if (fqdn) fqdn = fqdn.toLowerCase();
|
if (fqdn) fqdn = fqdn.toLowerCase();
|
||||||
const found = await isDomainConfigured({ id, fqdn });
|
const found = await isDomainConfigured({ id, fqdn });
|
||||||
if (found) {
|
if (found) {
|
||||||
throw { message: "Domain already configured" };
|
throw { message: 'Domain already configured' };
|
||||||
}
|
}
|
||||||
if (isDNSCheckEnabled && !forceSave && !isDev) {
|
if (isDNSCheckEnabled && !forceSave && !isDev) {
|
||||||
const hostname = request.hostname.split(':')[0]
|
const hostname = request.hostname.split(':')[0];
|
||||||
return await checkDomainsIsValidInDNS({ hostname, fqdn, dualCerts });
|
return await checkDomainsIsValidInDNS({ hostname, fqdn, dualCerts });
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
} catch ({ status, message }) {
|
} catch ({ status, message }) {
|
||||||
return errorHandler({ status, message })
|
return errorHandler({ status, message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export async function checkDNS(request: FastifyRequest<CheckDNS>) {
|
export async function checkDNS(request: FastifyRequest<CheckDNS>) {
|
||||||
try {
|
try {
|
||||||
const { domain } = request.params;
|
const { domain } = request.params;
|
||||||
await isDNSValid(request.hostname, domain);
|
await isDNSValid(request.hostname, domain);
|
||||||
return {}
|
return {};
|
||||||
} catch ({ status, message }) {
|
} catch ({ status, message }) {
|
||||||
return errorHandler({ status, message })
|
return errorHandler({ status, message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,82 +203,110 @@ export async function saveSSHKey(request: FastifyRequest<SaveSSHKey>, reply: Fas
|
|||||||
try {
|
try {
|
||||||
const teamId = request.user.teamId;
|
const teamId = request.user.teamId;
|
||||||
const { privateKey, name } = request.body;
|
const { privateKey, name } = request.body;
|
||||||
const found = await prisma.sshKey.findMany({ where: { name } })
|
const found = await prisma.sshKey.findMany({ where: { name } });
|
||||||
if (found.length > 0) {
|
if (found.length > 0) {
|
||||||
throw {
|
throw {
|
||||||
message: "Name already used. Choose another one please."
|
message: 'Name already used. Choose another one please.'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
const encryptedSSHKey = encrypt(privateKey);
|
||||||
const encryptedSSHKey = encrypt(privateKey)
|
await prisma.sshKey.create({
|
||||||
await prisma.sshKey.create({ data: { name, privateKey: encryptedSSHKey, team: { connect: { id: teamId } } } })
|
data: { name, privateKey: encryptedSSHKey, team: { connect: { id: teamId } } }
|
||||||
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 deleteSSHKey(request: FastifyRequest<OnlyIdInBody>, reply: FastifyReply) {
|
export async function deleteSSHKey(request: FastifyRequest<OnlyIdInBody>, reply: FastifyReply) {
|
||||||
try {
|
try {
|
||||||
const teamId = request.user.teamId;
|
const teamId = request.user.teamId;
|
||||||
const { id } = request.body;
|
const { id } = request.body;
|
||||||
await prisma.sshKey.deleteMany({ where: { id, teamId } })
|
await prisma.sshKey.deleteMany({ where: { id, teamId } });
|
||||||
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 deleteCertificates(request: FastifyRequest<OnlyIdInBody>, reply: FastifyReply) {
|
export async function deleteCertificates(
|
||||||
|
request: FastifyRequest<OnlyIdInBody>,
|
||||||
|
reply: FastifyReply
|
||||||
|
) {
|
||||||
try {
|
try {
|
||||||
const teamId = request.user.teamId;
|
const teamId = request.user.teamId;
|
||||||
const { id } = request.body;
|
const { id } = request.body;
|
||||||
await executeCommand({ command: `docker exec coolify-proxy sh -c 'rm -f /etc/traefik/acme/custom/${id}-key.pem /etc/traefik/acme/custom/${id}-cert.pem'`, shell: true })
|
await executeCommand({
|
||||||
await prisma.certificate.deleteMany({ where: { id, teamId } })
|
command: `docker exec coolify-proxy sh -c 'rm -f /etc/traefik/acme/custom/${id}-key.pem /etc/traefik/acme/custom/${id}-cert.pem'`,
|
||||||
return reply.code(201).send()
|
shell: true
|
||||||
|
});
|
||||||
|
await prisma.certificate.deleteMany({ where: { id, teamId } });
|
||||||
|
return reply.code(201).send();
|
||||||
} catch ({ status, message }) {
|
} catch ({ status, message }) {
|
||||||
return errorHandler({ status, message })
|
return errorHandler({ status, message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function setDockerRegistry(request: FastifyRequest<SetDefaultRegistry>, reply: FastifyReply) {
|
export async function setDockerRegistry(
|
||||||
|
request: FastifyRequest<SetDefaultRegistry>,
|
||||||
|
reply: FastifyReply
|
||||||
|
) {
|
||||||
try {
|
try {
|
||||||
const teamId = request.user.teamId;
|
const teamId = request.user.teamId;
|
||||||
const { id, username, password } = request.body;
|
const { id, username, password } = request.body;
|
||||||
|
|
||||||
let encryptedPassword = ''
|
let encryptedPassword = '';
|
||||||
if (password) encryptedPassword = encrypt(password)
|
if (password) encryptedPassword = encrypt(password);
|
||||||
|
|
||||||
if (teamId === '0') {
|
if (teamId === '0') {
|
||||||
await prisma.dockerRegistry.update({ where: { id }, data: { username, password: encryptedPassword } })
|
await prisma.dockerRegistry.update({
|
||||||
|
where: { id },
|
||||||
|
data: { username, password: encryptedPassword }
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
await prisma.dockerRegistry.updateMany({ where: { id, teamId }, data: { username, password: encryptedPassword } })
|
await prisma.dockerRegistry.updateMany({
|
||||||
|
where: { id, teamId },
|
||||||
|
data: { username, password: encryptedPassword }
|
||||||
|
});
|
||||||
}
|
}
|
||||||
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 addDockerRegistry(request: FastifyRequest<AddDefaultRegistry>, reply: FastifyReply) {
|
export async function addDockerRegistry(
|
||||||
|
request: FastifyRequest<AddDefaultRegistry>,
|
||||||
|
reply: FastifyReply
|
||||||
|
) {
|
||||||
try {
|
try {
|
||||||
const teamId = request.user.teamId;
|
const teamId = request.user.teamId;
|
||||||
const { name, url, username, password } = request.body;
|
const { name, url, username, password } = request.body;
|
||||||
|
|
||||||
let encryptedPassword = ''
|
let encryptedPassword = '';
|
||||||
if (password) encryptedPassword = encrypt(password)
|
if (password) encryptedPassword = encrypt(password);
|
||||||
await prisma.dockerRegistry.create({ data: { name, url, username, password: encryptedPassword, team: { connect: { id: teamId } } } })
|
await prisma.dockerRegistry.create({
|
||||||
|
data: { name, url, username, password: encryptedPassword, team: { connect: { id: teamId } } }
|
||||||
|
});
|
||||||
|
|
||||||
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 deleteDockerRegistry(request: FastifyRequest<OnlyIdInBody>, reply: FastifyReply) {
|
export async function deleteDockerRegistry(
|
||||||
|
request: FastifyRequest<OnlyIdInBody>,
|
||||||
|
reply: FastifyReply
|
||||||
|
) {
|
||||||
try {
|
try {
|
||||||
const teamId = request.user.teamId;
|
const teamId = request.user.teamId;
|
||||||
const { id } = request.body;
|
const { id } = request.body;
|
||||||
await prisma.application.updateMany({ where: { dockerRegistryId: id }, data: { dockerRegistryId: null } })
|
await prisma.application.updateMany({
|
||||||
await prisma.dockerRegistry.deleteMany({ where: { id, teamId } })
|
where: { dockerRegistryId: id },
|
||||||
return reply.code(201).send()
|
data: { dockerRegistryId: null }
|
||||||
|
});
|
||||||
|
await prisma.dockerRegistry.deleteMany({ where: { id, teamId } });
|
||||||
|
return reply.code(201).send();
|
||||||
} catch ({ status, message }) {
|
} catch ({ status, message }) {
|
||||||
return errorHandler({ status, message })
|
return errorHandler({ status, message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -42,8 +42,6 @@
|
|||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sentry/svelte": "7.21.1",
|
|
||||||
"@sentry/tracing": "7.21.1",
|
|
||||||
"@sveltejs/adapter-static": "1.0.0-next.48",
|
"@sveltejs/adapter-static": "1.0.0-next.48",
|
||||||
"@tailwindcss/typography": "0.5.8",
|
"@tailwindcss/typography": "0.5.8",
|
||||||
"cuid": "2.1.8",
|
"cuid": "2.1.8",
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
import * as Sentry from '@sentry/svelte';
|
|
||||||
export async function handle({ event, resolve }) {
|
export async function handle({ event, resolve }) {
|
||||||
const response = await resolve(event, { ssr: false });
|
const response = await resolve(event, { ssr: false });
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
export const handleError = ({ error, event }) => {
|
export const handleError = ({ error, event }) => {
|
||||||
Sentry.captureException(error, { event });
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
message: 'Whoops!',
|
message: 'Whoops!',
|
||||||
code: error?.code ?? 'UNKNOWN'
|
code: error?.code ?? 'UNKNOWN'
|
||||||
|
|||||||
@@ -65,7 +65,6 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
export let settings: any;
|
export let settings: any;
|
||||||
export let sentryDSN: any;
|
|
||||||
export let baseSettings: any;
|
export let baseSettings: any;
|
||||||
export let pendingInvitations: any = 0;
|
export let pendingInvitations: any = 0;
|
||||||
|
|
||||||
@@ -98,10 +97,6 @@
|
|||||||
import Toasts from '$lib/components/Toasts.svelte';
|
import Toasts from '$lib/components/Toasts.svelte';
|
||||||
import Tooltip from '$lib/components/Tooltip.svelte';
|
import Tooltip from '$lib/components/Tooltip.svelte';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import LocalePicker from '$lib/components/LocalePicker.svelte';
|
|
||||||
import * as Sentry from '@sentry/svelte';
|
|
||||||
import { BrowserTracing } from '@sentry/tracing';
|
|
||||||
import { dev } from '$app/env';
|
|
||||||
|
|
||||||
if (userId) $appSession.userId = userId;
|
if (userId) $appSession.userId = userId;
|
||||||
if (teamId) $appSession.teamId = teamId;
|
if (teamId) $appSession.teamId = teamId;
|
||||||
@@ -384,7 +379,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="drawer-side">
|
<div class="drawer-side">
|
||||||
<label for="main-drawer" class="drawer-overlay w-full" />
|
<label for="main-drawer" class="drawer-overlay w-full" />
|
||||||
<ul class="menu bg-coolgray-200 w-60 p-2 space-y-3 pt-4 ">
|
<ul class="menu bg-coolgray-200 w-60 p-2 space-y-3 pt-4">
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
class="no-underline icons hover:text-white hover:bg-pink-500"
|
class="no-underline icons hover:text-white hover:bg-pink-500"
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
"build:api": "NODE_ENV=production pnpm run --filter api build",
|
"build:api": "NODE_ENV=production pnpm run --filter api build",
|
||||||
"build:ui": "NODE_ENV=production pnpm run --filter ui build",
|
"build:ui": "NODE_ENV=production pnpm run --filter ui build",
|
||||||
"dockerlogin": "echo $DOCKER_PASS | docker login --username=$DOCKER_USER --password-stdin",
|
"dockerlogin": "echo $DOCKER_PASS | docker login --username=$DOCKER_USER --password-stdin",
|
||||||
"release:staging:amd": "docker build -t ghcr.io/coollabsio/coolify:next . && docker push ghcr.io/coollabsio/coolify:next",
|
"release:staging:amd": "docker build -t ghcr.io/coollabsio/coolify:v3 . && docker push ghcr.io/coollabsio/coolify:v3",
|
||||||
"release:local": "rm -fr ./local-serve && mkdir ./local-serve && pnpm build && cp -Rp apps/api/build/* ./local-serve && cp -Rp apps/ui/build/ ./local-serve/public && cp -Rp apps/api/prisma/ ./local-serve/prisma && cp -Rp apps/api/package.json ./local-serve && env | grep '^COOLIFY_' > ./local-serve/.env && cd ./local-serve && pnpm install . && pnpm start"
|
"release:local": "rm -fr ./local-serve && mkdir ./local-serve && pnpm build && cp -Rp apps/api/build/* ./local-serve && cp -Rp apps/ui/build/ ./local-serve/public && cp -Rp apps/api/prisma/ ./local-serve/prisma && cp -Rp apps/api/package.json ./local-serve && env | grep '^COOLIFY_' > ./local-serve/.env && cd ./local-serve && pnpm install . && pnpm start"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
Reference in New Issue
Block a user