Merged upstream and fixed expose port implementation
This commit is contained in:
@@ -1,10 +1,19 @@
|
||||
import { decrypt, encrypt } from '$lib/crypto';
|
||||
import { asyncExecShell, getEngine } from '$lib/common';
|
||||
|
||||
import { getDomain, removeDestinationDocker } from '$lib/common';
|
||||
import { removeDestinationDocker } from '$lib/common';
|
||||
import { prisma } from './common';
|
||||
|
||||
export async function listApplications(teamId) {
|
||||
import type {
|
||||
DestinationDocker,
|
||||
GitSource,
|
||||
Secret,
|
||||
ApplicationSettings,
|
||||
Application,
|
||||
ApplicationPersistentStorage
|
||||
} from '@prisma/client';
|
||||
|
||||
export async function listApplications(teamId: string): Promise<Application[]> {
|
||||
if (teamId === '0') {
|
||||
return await prisma.application.findMany({ include: { teams: true } });
|
||||
}
|
||||
@@ -14,7 +23,13 @@ export async function listApplications(teamId) {
|
||||
});
|
||||
}
|
||||
|
||||
export async function newApplication({ name, teamId }) {
|
||||
export async function newApplication({
|
||||
name,
|
||||
teamId
|
||||
}: {
|
||||
name: string;
|
||||
teamId: string;
|
||||
}): Promise<Application> {
|
||||
return await prisma.application.create({
|
||||
data: {
|
||||
name,
|
||||
@@ -24,34 +39,17 @@ export async function newApplication({ name, teamId }) {
|
||||
});
|
||||
}
|
||||
|
||||
export async function importApplication({
|
||||
name,
|
||||
teamId,
|
||||
fqdn,
|
||||
port,
|
||||
buildCommand,
|
||||
startCommand,
|
||||
installCommand
|
||||
}) {
|
||||
return await prisma.application.create({
|
||||
data: {
|
||||
name,
|
||||
fqdn,
|
||||
port,
|
||||
buildCommand,
|
||||
startCommand,
|
||||
installCommand,
|
||||
teams: { connect: { id: teamId } }
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export async function removeApplication({ id, teamId }) {
|
||||
const { fqdn, destinationDockerId, destinationDocker } = await prisma.application.findUnique({
|
||||
export async function removeApplication({
|
||||
id,
|
||||
teamId
|
||||
}: {
|
||||
id: string;
|
||||
teamId: string;
|
||||
}): Promise<void> {
|
||||
const { destinationDockerId, destinationDocker } = await prisma.application.findUnique({
|
||||
where: { id },
|
||||
include: { destinationDocker: true }
|
||||
});
|
||||
const domain = getDomain(fqdn);
|
||||
if (destinationDockerId) {
|
||||
const host = getEngine(destinationDocker.engine);
|
||||
const { stdout: containers } = await asyncExecShell(
|
||||
@@ -62,7 +60,6 @@ export async function removeApplication({ id, teamId }) {
|
||||
for (const container of containersArray) {
|
||||
const containerObj = JSON.parse(container);
|
||||
const id = containerObj.ID;
|
||||
const preview = containerObj.Image.split('-')[1];
|
||||
await removeDestinationDocker({ id, engine: destinationDocker.engine });
|
||||
}
|
||||
}
|
||||
@@ -80,9 +77,23 @@ export async function removeApplication({ id, teamId }) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function getApplicationWebhook({ projectId, branch }) {
|
||||
export async function getApplicationWebhook({
|
||||
projectId,
|
||||
branch
|
||||
}: {
|
||||
projectId: number;
|
||||
branch: string;
|
||||
}): Promise<
|
||||
Application & {
|
||||
destinationDocker: DestinationDocker;
|
||||
settings: ApplicationSettings;
|
||||
gitSource: GitSource;
|
||||
secrets: Secret[];
|
||||
persistentStorage: ApplicationPersistentStorage[];
|
||||
}
|
||||
> {
|
||||
try {
|
||||
let application = await prisma.application.findFirst({
|
||||
const application = await prisma.application.findFirst({
|
||||
where: { projectId, branch, settings: { autodeploy: true } },
|
||||
include: {
|
||||
destinationDocker: true,
|
||||
@@ -131,16 +142,17 @@ export async function getApplicationWebhook({ projectId, branch }) {
|
||||
throw { status: 404, body: { message: e.message } };
|
||||
}
|
||||
}
|
||||
export async function getApplicationById({ id }) {
|
||||
const body = await prisma.application.findFirst({
|
||||
where: { id },
|
||||
include: { destinationDocker: true }
|
||||
});
|
||||
|
||||
return { ...body };
|
||||
}
|
||||
export async function getApplication({ id, teamId }) {
|
||||
let body = {};
|
||||
export async function getApplication({ id, teamId }: { id: string; teamId: string }): Promise<
|
||||
Application & {
|
||||
destinationDocker: DestinationDocker;
|
||||
settings: ApplicationSettings;
|
||||
gitSource: GitSource;
|
||||
secrets: Secret[];
|
||||
persistentStorage: ApplicationPersistentStorage[];
|
||||
}
|
||||
> {
|
||||
let body;
|
||||
if (teamId === '0') {
|
||||
body = await prisma.application.findFirst({
|
||||
where: { id },
|
||||
@@ -194,7 +206,14 @@ export async function configureGitRepository({
|
||||
projectId,
|
||||
webhookToken,
|
||||
autodeploy
|
||||
}) {
|
||||
}: {
|
||||
id: string;
|
||||
repository: string;
|
||||
branch: string;
|
||||
projectId: number;
|
||||
webhookToken: string;
|
||||
autodeploy: boolean;
|
||||
}): Promise<void> {
|
||||
if (webhookToken) {
|
||||
const encryptedWebhookToken = encrypt(webhookToken);
|
||||
await prisma.application.update({
|
||||
@@ -224,7 +243,10 @@ export async function configureGitRepository({
|
||||
}
|
||||
}
|
||||
|
||||
export async function configureBuildPack({ id, buildPack }) {
|
||||
export async function configureBuildPack({
|
||||
id,
|
||||
buildPack
|
||||
}: Pick<Application, 'id' | 'buildPack'>): Promise<Application> {
|
||||
return await prisma.application.update({ where: { id }, data: { buildPack } });
|
||||
}
|
||||
|
||||
@@ -242,8 +264,29 @@ export async function configureApplication({
|
||||
publishDirectory,
|
||||
pythonWSGI,
|
||||
pythonModule,
|
||||
pythonVariable
|
||||
}) {
|
||||
pythonVariable,
|
||||
dockerFileLocation,
|
||||
denoMainFile,
|
||||
denoOptions
|
||||
}: {
|
||||
id: string;
|
||||
buildPack: string;
|
||||
name: string;
|
||||
fqdn: string;
|
||||
port: number;
|
||||
exposePort: number;
|
||||
installCommand: string;
|
||||
buildCommand: string;
|
||||
startCommand: string;
|
||||
baseDirectory: string;
|
||||
publishDirectory: string;
|
||||
pythonWSGI: string;
|
||||
pythonModule: string;
|
||||
pythonVariable: string;
|
||||
dockerFileLocation: string;
|
||||
denoMainFile: string;
|
||||
denoOptions: string;
|
||||
}): Promise<Application> {
|
||||
return await prisma.application.update({
|
||||
where: { id },
|
||||
data: {
|
||||
@@ -259,16 +302,32 @@ export async function configureApplication({
|
||||
publishDirectory,
|
||||
pythonWSGI,
|
||||
pythonModule,
|
||||
pythonVariable
|
||||
pythonVariable,
|
||||
dockerFileLocation,
|
||||
denoMainFile,
|
||||
denoOptions
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export async function checkDoubleBranch(branch, projectId) {
|
||||
export async function checkDoubleBranch(branch: string, projectId: number): Promise<boolean> {
|
||||
const applications = await prisma.application.findMany({ where: { branch, projectId } });
|
||||
return applications.length > 1;
|
||||
}
|
||||
export async function setApplicationSettings({ id, debug, previews, dualCerts, autodeploy }) {
|
||||
|
||||
export async function setApplicationSettings({
|
||||
id,
|
||||
debug,
|
||||
previews,
|
||||
dualCerts,
|
||||
autodeploy
|
||||
}: {
|
||||
id: string;
|
||||
debug: boolean;
|
||||
previews: boolean;
|
||||
dualCerts: boolean;
|
||||
autodeploy: boolean;
|
||||
}): Promise<Application & { destinationDocker: DestinationDocker }> {
|
||||
return await prisma.application.update({
|
||||
where: { id },
|
||||
data: { settings: { update: { debug, previews, dualCerts, autodeploy } } },
|
||||
@@ -276,29 +335,6 @@ export async function setApplicationSettings({ id, debug, previews, dualCerts, a
|
||||
});
|
||||
}
|
||||
|
||||
export async function createBuild({
|
||||
id,
|
||||
applicationId,
|
||||
destinationDockerId,
|
||||
gitSourceId,
|
||||
githubAppId,
|
||||
gitlabAppId,
|
||||
type
|
||||
}) {
|
||||
return await prisma.build.create({
|
||||
data: {
|
||||
id,
|
||||
applicationId,
|
||||
destinationDockerId,
|
||||
gitSourceId,
|
||||
githubAppId,
|
||||
gitlabAppId,
|
||||
status: 'running',
|
||||
type
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export async function getPersistentStorage(id) {
|
||||
export async function getPersistentStorage(id: string): Promise<ApplicationPersistentStorage[]> {
|
||||
return await prisma.applicationPersistentStorage.findMany({ where: { applicationId: id } });
|
||||
}
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
import { getDomain } from '$lib/common';
|
||||
import { prisma } from './common';
|
||||
import type { Application, ServiceSecret, DestinationDocker, Secret } from '@prisma/client';
|
||||
|
||||
export async function isBranchAlreadyUsed({ repository, branch, id }) {
|
||||
export async function isBranchAlreadyUsed({
|
||||
repository,
|
||||
branch,
|
||||
id
|
||||
}: {
|
||||
id: string;
|
||||
repository: string;
|
||||
branch: string;
|
||||
}): Promise<Application> {
|
||||
const application = await prisma.application.findUnique({
|
||||
where: { id },
|
||||
include: { gitSource: true }
|
||||
@@ -11,18 +20,42 @@ export async function isBranchAlreadyUsed({ repository, branch, id }) {
|
||||
});
|
||||
}
|
||||
|
||||
export async function isDockerNetworkExists({ network }) {
|
||||
export async function isDockerNetworkExists({
|
||||
network
|
||||
}: {
|
||||
network: string;
|
||||
}): Promise<DestinationDocker> {
|
||||
return await prisma.destinationDocker.findFirst({ where: { network } });
|
||||
}
|
||||
|
||||
export async function isServiceSecretExists({ id, name }) {
|
||||
export async function isServiceSecretExists({
|
||||
id,
|
||||
name
|
||||
}: {
|
||||
id: string;
|
||||
name: string;
|
||||
}): Promise<ServiceSecret> {
|
||||
return await prisma.serviceSecret.findFirst({ where: { name, serviceId: id } });
|
||||
}
|
||||
export async function isSecretExists({ id, name, isPRMRSecret }) {
|
||||
export async function isSecretExists({
|
||||
id,
|
||||
name,
|
||||
isPRMRSecret
|
||||
}: {
|
||||
id: string;
|
||||
name: string;
|
||||
isPRMRSecret: boolean;
|
||||
}): Promise<Secret> {
|
||||
return await prisma.secret.findFirst({ where: { name, applicationId: id, isPRMRSecret } });
|
||||
}
|
||||
|
||||
export async function isDomainConfigured({ id, fqdn }) {
|
||||
export async function isDomainConfigured({
|
||||
id,
|
||||
fqdn
|
||||
}: {
|
||||
id: string;
|
||||
fqdn: string;
|
||||
}): Promise<boolean> {
|
||||
const domain = getDomain(fqdn);
|
||||
const nakedDomain = domain.replace('www.', '');
|
||||
const foundApp = await prisma.application.findFirst({
|
||||
@@ -55,6 +88,5 @@ export async function isDomainConfigured({ id, fqdn }) {
|
||||
},
|
||||
select: { fqdn: true }
|
||||
});
|
||||
if (foundApp || foundService || coolifyFqdn) return true;
|
||||
return false;
|
||||
return !!(foundApp || foundService || coolifyFqdn);
|
||||
}
|
||||
|
||||
@@ -6,11 +6,12 @@ import {
|
||||
} from '$lib/components/common';
|
||||
import * as Prisma from '@prisma/client';
|
||||
import { default as ProdPrisma } from '@prisma/client';
|
||||
import type { PrismaClientOptions } from '@prisma/client/runtime';
|
||||
import type { Database, DatabaseSettings } from '@prisma/client';
|
||||
import generator from 'generate-password';
|
||||
import forge from 'node-forge';
|
||||
import getPort, { portNumbers } from 'get-port';
|
||||
|
||||
export function generatePassword(length = 24) {
|
||||
export function generatePassword(length = 24): string {
|
||||
return generator.generate({
|
||||
length,
|
||||
numbers: true,
|
||||
@@ -30,8 +31,14 @@ export const prisma = new PrismaClient({
|
||||
rejectOnNotFound: false
|
||||
});
|
||||
|
||||
export function ErrorHandler(e) {
|
||||
if (e! instanceof Error) {
|
||||
export function ErrorHandler(e: {
|
||||
stdout?;
|
||||
message?: string;
|
||||
status?: number;
|
||||
name?: string;
|
||||
error?: string;
|
||||
}): { status: number; body: { message: string; error: string } } {
|
||||
if (e && e instanceof Error) {
|
||||
e = new Error(e.toString());
|
||||
}
|
||||
let truncatedError = e;
|
||||
@@ -39,8 +46,7 @@ export function ErrorHandler(e) {
|
||||
truncatedError = e.stdout;
|
||||
}
|
||||
if (e.message?.includes('docker run')) {
|
||||
let truncatedArray = [];
|
||||
truncatedArray = truncatedError.message.split('-').filter((line) => {
|
||||
const truncatedArray: string[] = truncatedError.message.split('-').filter((line) => {
|
||||
if (!line.startsWith('e ')) {
|
||||
return line;
|
||||
}
|
||||
@@ -68,11 +74,11 @@ export function ErrorHandler(e) {
|
||||
payload.body.message = 'Already exists. Choose another name.';
|
||||
}
|
||||
}
|
||||
// console.error(e)
|
||||
return payload;
|
||||
}
|
||||
|
||||
export async function generateSshKeyPair(): Promise<{ publicKey: string; privateKey: string }> {
|
||||
return await new Promise(async (resolve, reject) => {
|
||||
return await new Promise((resolve, reject) => {
|
||||
forge.pki.rsa.generateKeyPair({ bits: 4096, workers: -1 }, function (err, keys) {
|
||||
if (keys) {
|
||||
resolve({
|
||||
@@ -86,35 +92,94 @@ export async function generateSshKeyPair(): Promise<{ publicKey: string; private
|
||||
});
|
||||
}
|
||||
|
||||
export function getVersions(type) {
|
||||
export function getVersions(type: string): string[] {
|
||||
const found = supportedDatabaseTypesAndVersions.find((t) => t.name === type);
|
||||
if (found) {
|
||||
return found.versions;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
export function getDatabaseImage(type) {
|
||||
|
||||
export function getDatabaseImage(type: string): string {
|
||||
const found = supportedDatabaseTypesAndVersions.find((t) => t.name === type);
|
||||
if (found) {
|
||||
return found.baseImage;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
export function getServiceImage(type) {
|
||||
|
||||
export function getServiceImage(type: string): string {
|
||||
const found = supportedServiceTypesAndVersions.find((t) => t.name === type);
|
||||
if (found) {
|
||||
return found.baseImage;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
export function getServiceImages(type) {
|
||||
|
||||
export function getServiceImages(type: string): string[] {
|
||||
const found = supportedServiceTypesAndVersions.find((t) => t.name === type);
|
||||
if (found) {
|
||||
return found.images;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
export function generateDatabaseConfiguration(database) {
|
||||
|
||||
export function generateDatabaseConfiguration(database: Database & { settings: DatabaseSettings }):
|
||||
| {
|
||||
volume: string;
|
||||
image: string;
|
||||
ulimits: Record<string, unknown>;
|
||||
privatePort: number;
|
||||
environmentVariables: {
|
||||
MYSQL_DATABASE: string;
|
||||
MYSQL_PASSWORD: string;
|
||||
MYSQL_ROOT_USER: string;
|
||||
MYSQL_USER: string;
|
||||
MYSQL_ROOT_PASSWORD: string;
|
||||
};
|
||||
}
|
||||
| {
|
||||
volume: string;
|
||||
image: string;
|
||||
ulimits: Record<string, unknown>;
|
||||
privatePort: number;
|
||||
environmentVariables: {
|
||||
MONGODB_ROOT_USER: string;
|
||||
MONGODB_ROOT_PASSWORD: string;
|
||||
};
|
||||
}
|
||||
| {
|
||||
volume: string;
|
||||
image: string;
|
||||
ulimits: Record<string, unknown>;
|
||||
privatePort: number;
|
||||
environmentVariables: {
|
||||
POSTGRESQL_POSTGRES_PASSWORD: string;
|
||||
POSTGRESQL_USERNAME: string;
|
||||
POSTGRESQL_PASSWORD: string;
|
||||
POSTGRESQL_DATABASE: string;
|
||||
};
|
||||
}
|
||||
| {
|
||||
volume: string;
|
||||
image: string;
|
||||
ulimits: Record<string, unknown>;
|
||||
privatePort: number;
|
||||
environmentVariables: {
|
||||
REDIS_AOF_ENABLED: string;
|
||||
REDIS_PASSWORD: string;
|
||||
};
|
||||
}
|
||||
| {
|
||||
volume: string;
|
||||
image: string;
|
||||
ulimits: Record<string, unknown>;
|
||||
privatePort: number;
|
||||
environmentVariables: {
|
||||
COUCHDB_PASSWORD: string;
|
||||
COUCHDB_USER: string;
|
||||
};
|
||||
} {
|
||||
const {
|
||||
id,
|
||||
dbUser,
|
||||
@@ -129,7 +194,6 @@ export function generateDatabaseConfiguration(database) {
|
||||
const baseImage = getDatabaseImage(type);
|
||||
if (type === 'mysql') {
|
||||
return {
|
||||
// url: `mysql://${dbUser}:${dbUserPassword}@${id}:${isPublic ? port : 3306}/${defaultDatabase}`,
|
||||
privatePort: 3306,
|
||||
environmentVariables: {
|
||||
MYSQL_USER: dbUser,
|
||||
@@ -144,7 +208,6 @@ export function generateDatabaseConfiguration(database) {
|
||||
};
|
||||
} else if (type === 'mongodb') {
|
||||
return {
|
||||
// url: `mongodb://${dbUser}:${dbUserPassword}@${id}:${isPublic ? port : 27017}/${defaultDatabase}`,
|
||||
privatePort: 27017,
|
||||
environmentVariables: {
|
||||
MONGODB_ROOT_USER: rootUser,
|
||||
@@ -156,7 +219,6 @@ export function generateDatabaseConfiguration(database) {
|
||||
};
|
||||
} else if (type === 'postgresql') {
|
||||
return {
|
||||
// url: `psql://${dbUser}:${dbUserPassword}@${id}:${isPublic ? port : 5432}/${defaultDatabase}`,
|
||||
privatePort: 5432,
|
||||
environmentVariables: {
|
||||
POSTGRESQL_POSTGRES_PASSWORD: rootUserPassword,
|
||||
@@ -170,7 +232,6 @@ export function generateDatabaseConfiguration(database) {
|
||||
};
|
||||
} else if (type === 'redis') {
|
||||
return {
|
||||
// url: `redis://${dbUser}:${dbUserPassword}@${id}:${isPublic ? port : 6379}/${defaultDatabase}`,
|
||||
privatePort: 6379,
|
||||
environmentVariables: {
|
||||
REDIS_PASSWORD: dbUserPassword,
|
||||
@@ -182,7 +243,6 @@ export function generateDatabaseConfiguration(database) {
|
||||
};
|
||||
} else if (type === 'couchdb') {
|
||||
return {
|
||||
// url: `couchdb://${dbUser}:${dbUserPassword}@${id}:${isPublic ? port : 5984}/${defaultDatabase}`,
|
||||
privatePort: 5984,
|
||||
environmentVariables: {
|
||||
COUCHDB_PASSWORD: dbUserPassword,
|
||||
@@ -193,18 +253,30 @@ export function generateDatabaseConfiguration(database) {
|
||||
ulimits: {}
|
||||
};
|
||||
}
|
||||
// } else if (type === 'clickhouse') {
|
||||
// return {
|
||||
// url: `clickhouse://${dbUser}:${dbUserPassword}@${id}:${port}/${defaultDatabase}`,
|
||||
// privatePort: 9000,
|
||||
// image: `bitnami/clickhouse-server:${version}`,
|
||||
// volume: `${id}-${type}-data:/var/lib/clickhouse`,
|
||||
// ulimits: {
|
||||
// nofile: {
|
||||
// soft: 262144,
|
||||
// hard: 262144
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
export async function getFreePort() {
|
||||
const data = await prisma.setting.findFirst();
|
||||
const { minPort, maxPort } = data;
|
||||
|
||||
const dbUsed = await (
|
||||
await prisma.database.findMany({
|
||||
where: { publicPort: { not: null } },
|
||||
select: { publicPort: true }
|
||||
})
|
||||
).map((a) => a.publicPort);
|
||||
const wpFtpUsed = await (
|
||||
await prisma.wordpress.findMany({
|
||||
where: { ftpPublicPort: { not: null } },
|
||||
select: { ftpPublicPort: true }
|
||||
})
|
||||
).map((a) => a.ftpPublicPort);
|
||||
const wpUsed = await (
|
||||
await prisma.wordpress.findMany({
|
||||
where: { mysqlPublicPort: { not: null } },
|
||||
select: { mysqlPublicPort: true }
|
||||
})
|
||||
).map((a) => a.mysqlPublicPort);
|
||||
const usedPorts = [...dbUsed, ...wpFtpUsed, ...wpUsed];
|
||||
return await getPort({ port: portNumbers(minPort, maxPort), exclude: usedPorts });
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { decrypt, encrypt } from '$lib/crypto';
|
||||
import * as db from '$lib/database';
|
||||
import cuid from 'cuid';
|
||||
import { generatePassword } from '.';
|
||||
import { prisma, ErrorHandler } from './common';
|
||||
import getPort, { portNumbers } from 'get-port';
|
||||
import { prisma } from './common';
|
||||
import { asyncExecShell, getEngine, removeContainer } from '$lib/common';
|
||||
import type { Database, DatabaseSettings, DestinationDocker } from '@prisma/client';
|
||||
|
||||
export async function listDatabases(teamId) {
|
||||
export async function listDatabases(teamId: string): Promise<Database[]> {
|
||||
if (teamId === '0') {
|
||||
return await prisma.database.findMany({ include: { teams: true } });
|
||||
} else {
|
||||
@@ -16,7 +15,14 @@ export async function listDatabases(teamId) {
|
||||
});
|
||||
}
|
||||
}
|
||||
export async function newDatabase({ name, teamId }) {
|
||||
|
||||
export async function newDatabase({
|
||||
name,
|
||||
teamId
|
||||
}: {
|
||||
name: string;
|
||||
teamId: string;
|
||||
}): Promise<Database> {
|
||||
const dbUser = cuid();
|
||||
const dbUserPassword = encrypt(generatePassword());
|
||||
const rootUser = cuid();
|
||||
@@ -37,8 +43,14 @@ export async function newDatabase({ name, teamId }) {
|
||||
});
|
||||
}
|
||||
|
||||
export async function getDatabase({ id, teamId }) {
|
||||
let body = {};
|
||||
export async function getDatabase({
|
||||
id,
|
||||
teamId
|
||||
}: {
|
||||
id: string;
|
||||
teamId: string;
|
||||
}): Promise<Database & { destinationDocker: DestinationDocker; settings: DatabaseSettings }> {
|
||||
let body;
|
||||
if (teamId === '0') {
|
||||
body = await prisma.database.findFirst({
|
||||
where: { id },
|
||||
@@ -50,20 +62,25 @@ export async function getDatabase({ id, teamId }) {
|
||||
include: { destinationDocker: true, settings: true }
|
||||
});
|
||||
}
|
||||
|
||||
if (body.dbUserPassword) body.dbUserPassword = decrypt(body.dbUserPassword);
|
||||
if (body.rootUserPassword) body.rootUserPassword = decrypt(body.rootUserPassword);
|
||||
|
||||
return { ...body };
|
||||
return body;
|
||||
}
|
||||
|
||||
export async function removeDatabase({ id }) {
|
||||
export async function removeDatabase({ id }: { id: string }): Promise<void> {
|
||||
await prisma.databaseSettings.deleteMany({ where: { databaseId: id } });
|
||||
await prisma.database.delete({ where: { id } });
|
||||
return;
|
||||
}
|
||||
|
||||
export async function configureDatabaseType({ id, type }) {
|
||||
export async function configureDatabaseType({
|
||||
id,
|
||||
type
|
||||
}: {
|
||||
id: string;
|
||||
type: string;
|
||||
}): Promise<Database> {
|
||||
return await prisma.database.update({
|
||||
where: { id },
|
||||
data: { type }
|
||||
@@ -79,7 +96,7 @@ export async function setDatabase({
|
||||
version?: string;
|
||||
isPublic?: boolean;
|
||||
appendOnly?: boolean;
|
||||
}) {
|
||||
}): Promise<Database> {
|
||||
return await prisma.database.update({
|
||||
where: { id },
|
||||
data: {
|
||||
@@ -97,7 +114,16 @@ export async function updateDatabase({
|
||||
rootUser,
|
||||
rootUserPassword,
|
||||
version
|
||||
}) {
|
||||
}: {
|
||||
id: string;
|
||||
name: string;
|
||||
defaultDatabase: string;
|
||||
dbUser: string;
|
||||
dbUserPassword: string;
|
||||
rootUser: string;
|
||||
rootUserPassword: string;
|
||||
version: string;
|
||||
}): Promise<Database> {
|
||||
const encryptedDbUserPassword = dbUserPassword && encrypt(dbUserPassword);
|
||||
const encryptedRootUserPassword = rootUserPassword && encrypt(rootUserPassword);
|
||||
return await prisma.database.update({
|
||||
@@ -114,7 +140,9 @@ export async function updateDatabase({
|
||||
});
|
||||
}
|
||||
|
||||
export async function stopDatabase(database) {
|
||||
export async function stopDatabase(
|
||||
database: Database & { destinationDocker: DestinationDocker }
|
||||
): Promise<boolean> {
|
||||
let everStarted = false;
|
||||
const {
|
||||
id,
|
||||
|
||||
@@ -1,11 +1,22 @@
|
||||
import { asyncExecShell, getEngine } from '$lib/common';
|
||||
import { decrypt, encrypt } from '$lib/crypto';
|
||||
import { dockerInstance } from '$lib/docker';
|
||||
import { startCoolifyProxy } from '$lib/haproxy';
|
||||
import { getDatabaseImage } from '.';
|
||||
import { prisma } from './common';
|
||||
import type { DestinationDocker, Service, Application, Prisma } from '@prisma/client';
|
||||
import type { CreateDockerDestination } from '$lib/types/destinations';
|
||||
|
||||
export async function listDestinations(teamId) {
|
||||
type DestinationConfigurationObject = {
|
||||
id: string;
|
||||
destinationId: string;
|
||||
};
|
||||
|
||||
type FindDestinationFromTeam = {
|
||||
id: string;
|
||||
teamId: string;
|
||||
};
|
||||
|
||||
export async function listDestinations(teamId: string): Promise<DestinationDocker[]> {
|
||||
if (teamId === '0') {
|
||||
return await prisma.destinationDocker.findMany({ include: { teams: true } });
|
||||
}
|
||||
@@ -15,19 +26,28 @@ export async function listDestinations(teamId) {
|
||||
});
|
||||
}
|
||||
|
||||
export async function configureDestinationForService({ id, destinationId }) {
|
||||
export async function configureDestinationForService({
|
||||
id,
|
||||
destinationId
|
||||
}: DestinationConfigurationObject): Promise<Service> {
|
||||
return await prisma.service.update({
|
||||
where: { id },
|
||||
data: { destinationDocker: { connect: { id: destinationId } } }
|
||||
});
|
||||
}
|
||||
export async function configureDestinationForApplication({ id, destinationId }) {
|
||||
export async function configureDestinationForApplication({
|
||||
id,
|
||||
destinationId
|
||||
}: DestinationConfigurationObject): Promise<Application> {
|
||||
return await prisma.application.update({
|
||||
where: { id },
|
||||
data: { destinationDocker: { connect: { id: destinationId } } }
|
||||
});
|
||||
}
|
||||
export async function configureDestinationForDatabase({ id, destinationId }) {
|
||||
export async function configureDestinationForDatabase({
|
||||
id,
|
||||
destinationId
|
||||
}: DestinationConfigurationObject): Promise<void> {
|
||||
await prisma.database.update({
|
||||
where: { id },
|
||||
data: { destinationDocker: { connect: { id: destinationId } } }
|
||||
@@ -48,7 +68,12 @@ export async function configureDestinationForDatabase({ id, destinationId }) {
|
||||
}
|
||||
}
|
||||
}
|
||||
export async function updateDestination({ id, name, engine, network }) {
|
||||
export async function updateDestination({
|
||||
id,
|
||||
name,
|
||||
engine,
|
||||
network
|
||||
}: Pick<DestinationDocker, 'id' | 'name' | 'engine' | 'network'>): Promise<DestinationDocker> {
|
||||
return await prisma.destinationDocker.update({ where: { id }, data: { name, engine, network } });
|
||||
}
|
||||
|
||||
@@ -58,13 +83,8 @@ export async function newRemoteDestination({
|
||||
engine,
|
||||
network,
|
||||
isCoolifyProxyUsed,
|
||||
remoteEngine,
|
||||
ipAddress,
|
||||
user,
|
||||
port,
|
||||
sshPrivateKey
|
||||
}) {
|
||||
const encryptedPrivateKey = encrypt(sshPrivateKey);
|
||||
remoteEngine
|
||||
}: CreateDockerDestination): Promise<string> {
|
||||
const destination = await prisma.destinationDocker.create({
|
||||
data: {
|
||||
name,
|
||||
@@ -72,16 +92,18 @@ export async function newRemoteDestination({
|
||||
engine,
|
||||
network,
|
||||
isCoolifyProxyUsed,
|
||||
remoteEngine,
|
||||
ipAddress,
|
||||
user,
|
||||
port,
|
||||
sshPrivateKey: encryptedPrivateKey
|
||||
remoteEngine
|
||||
}
|
||||
});
|
||||
return destination.id;
|
||||
}
|
||||
export async function newLocalDestination({ name, teamId, engine, network, isCoolifyProxyUsed }) {
|
||||
export async function newLocalDestination({
|
||||
name,
|
||||
teamId,
|
||||
engine,
|
||||
network,
|
||||
isCoolifyProxyUsed
|
||||
}: CreateDockerDestination): Promise<string> {
|
||||
const host = getEngine(engine);
|
||||
const docker = dockerInstance({ destinationDocker: { engine, network } });
|
||||
const found = await docker.engine.listNetworks({ filters: { name: [`^${network}$`] } });
|
||||
@@ -99,18 +121,14 @@ export async function newLocalDestination({ name, teamId, engine, network, isCoo
|
||||
(destination) => destination.network !== network && destination.isCoolifyProxyUsed === true
|
||||
);
|
||||
if (proxyConfigured) {
|
||||
if (proxyConfigured.isCoolifyProxyUsed) {
|
||||
isCoolifyProxyUsed = true;
|
||||
} else {
|
||||
isCoolifyProxyUsed = false;
|
||||
}
|
||||
isCoolifyProxyUsed = !!proxyConfigured.isCoolifyProxyUsed;
|
||||
}
|
||||
await prisma.destinationDocker.updateMany({ where: { engine }, data: { isCoolifyProxyUsed } });
|
||||
}
|
||||
if (isCoolifyProxyUsed) await startCoolifyProxy(engine);
|
||||
return destination.id;
|
||||
}
|
||||
export async function removeDestination({ id }) {
|
||||
export async function removeDestination({ id }: Pick<DestinationDocker, 'id'>): Promise<void> {
|
||||
const destination = await prisma.destinationDocker.delete({ where: { id } });
|
||||
if (destination.isCoolifyProxyUsed) {
|
||||
const host = getEngine(destination.engine);
|
||||
@@ -127,8 +145,11 @@ export async function removeDestination({ id }) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function getDestination({ id, teamId }) {
|
||||
let destination = {};
|
||||
export async function getDestination({
|
||||
id,
|
||||
teamId
|
||||
}: FindDestinationFromTeam): Promise<DestinationDocker & { sshPrivateKey?: string }> {
|
||||
let destination;
|
||||
if (teamId === '0') {
|
||||
destination = await prisma.destinationDocker.findFirst({
|
||||
where: { id }
|
||||
@@ -141,13 +162,22 @@ export async function getDestination({ id, teamId }) {
|
||||
|
||||
return destination;
|
||||
}
|
||||
export async function getDestinationByApplicationId({ id, teamId }) {
|
||||
export async function getDestinationByApplicationId({
|
||||
id,
|
||||
teamId
|
||||
}: FindDestinationFromTeam): Promise<DestinationDocker> {
|
||||
return await prisma.destinationDocker.findFirst({
|
||||
where: { application: { some: { id } }, teams: { some: { id: teamId } } }
|
||||
});
|
||||
}
|
||||
|
||||
export async function setDestinationSettings({ engine, isCoolifyProxyUsed }) {
|
||||
export async function setDestinationSettings({
|
||||
engine,
|
||||
isCoolifyProxyUsed
|
||||
}: {
|
||||
engine: string;
|
||||
isCoolifyProxyUsed: boolean;
|
||||
}): Promise<Prisma.BatchPayload> {
|
||||
return await prisma.destinationDocker.updateMany({
|
||||
where: { engine },
|
||||
data: { isCoolifyProxyUsed }
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { decrypt, encrypt } from '$lib/crypto';
|
||||
import { prisma } from './common';
|
||||
import type { GithubApp, GitlabApp, GitSource, Prisma, Application } from '@prisma/client';
|
||||
|
||||
export async function listSources(teamId) {
|
||||
export async function listSources(
|
||||
teamId: string | Prisma.StringFilter
|
||||
): Promise<(GitSource & { githubApp?: GithubApp; gitlabApp?: GitlabApp })[]> {
|
||||
if (teamId === '0') {
|
||||
return await prisma.gitSource.findMany({
|
||||
include: { githubApp: true, gitlabApp: true, teams: true }
|
||||
@@ -13,7 +16,13 @@ export async function listSources(teamId) {
|
||||
});
|
||||
}
|
||||
|
||||
export async function newSource({ teamId, name }) {
|
||||
export async function newSource({
|
||||
name,
|
||||
teamId
|
||||
}: {
|
||||
name: string;
|
||||
teamId: string;
|
||||
}): Promise<GitSource> {
|
||||
return await prisma.gitSource.create({
|
||||
data: {
|
||||
name,
|
||||
@@ -21,7 +30,7 @@ export async function newSource({ teamId, name }) {
|
||||
}
|
||||
});
|
||||
}
|
||||
export async function removeSource({ id }) {
|
||||
export async function removeSource({ id }: { id: string }): Promise<void> {
|
||||
const source = await prisma.gitSource.delete({
|
||||
where: { id },
|
||||
include: { githubApp: true, gitlabApp: true }
|
||||
@@ -30,8 +39,14 @@ export async function removeSource({ id }) {
|
||||
if (source.gitlabAppId) await prisma.gitlabApp.delete({ where: { id: source.gitlabAppId } });
|
||||
}
|
||||
|
||||
export async function getSource({ id, teamId }) {
|
||||
let body = {};
|
||||
export async function getSource({
|
||||
id,
|
||||
teamId
|
||||
}: {
|
||||
id: string;
|
||||
teamId: string;
|
||||
}): Promise<GitSource & { githubApp: GithubApp; gitlabApp: GitlabApp }> {
|
||||
let body;
|
||||
if (teamId === '0') {
|
||||
body = await prisma.gitSource.findFirst({
|
||||
where: { id },
|
||||
@@ -51,8 +66,11 @@ export async function getSource({ id, teamId }) {
|
||||
if (body?.gitlabApp?.appSecret) body.gitlabApp.appSecret = decrypt(body.gitlabApp.appSecret);
|
||||
return body;
|
||||
}
|
||||
export async function addGitHubSource({ id, teamId, type, name, htmlUrl, apiUrl }) {
|
||||
await prisma.gitSource.update({ where: { id }, data: { type, name, htmlUrl, apiUrl } });
|
||||
export async function addGitHubSource({ id, teamId, type, name, htmlUrl, apiUrl, organization }) {
|
||||
await prisma.gitSource.update({
|
||||
where: { id },
|
||||
data: { type, name, htmlUrl, apiUrl, organization }
|
||||
});
|
||||
return await prisma.githubApp.create({
|
||||
data: {
|
||||
teams: { connect: { id: teamId } },
|
||||
@@ -72,7 +90,7 @@ export async function addGitLabSource({
|
||||
appSecret,
|
||||
groupName
|
||||
}) {
|
||||
const encrptedAppSecret = encrypt(appSecret);
|
||||
const encryptedAppSecret = encrypt(appSecret);
|
||||
await prisma.gitSource.update({ where: { id }, data: { type, apiUrl, htmlUrl, name } });
|
||||
return await prisma.gitlabApp.create({
|
||||
data: {
|
||||
@@ -80,19 +98,35 @@ export async function addGitLabSource({
|
||||
appId,
|
||||
oauthId,
|
||||
groupName,
|
||||
appSecret: encrptedAppSecret,
|
||||
appSecret: encryptedAppSecret,
|
||||
gitSource: { connect: { id } }
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export async function configureGitsource({ id, gitSourceId }) {
|
||||
export async function configureGitsource({
|
||||
id,
|
||||
gitSourceId
|
||||
}: {
|
||||
id: string;
|
||||
gitSourceId: string;
|
||||
}): Promise<Application> {
|
||||
return await prisma.application.update({
|
||||
where: { id },
|
||||
data: { gitSource: { connect: { id: gitSourceId } } }
|
||||
});
|
||||
}
|
||||
export async function updateGitsource({ id, name, htmlUrl, apiUrl }) {
|
||||
export async function updateGitsource({
|
||||
id,
|
||||
name,
|
||||
htmlUrl,
|
||||
apiUrl
|
||||
}: {
|
||||
id: string;
|
||||
name: string;
|
||||
htmlUrl: string;
|
||||
apiUrl: string;
|
||||
}): Promise<GitSource> {
|
||||
return await prisma.gitSource.update({
|
||||
where: { id },
|
||||
data: { name, htmlUrl, apiUrl }
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
import { decrypt, encrypt } from '$lib/crypto';
|
||||
import { prisma } from './common';
|
||||
import type { GithubApp } from '@prisma/client';
|
||||
|
||||
export async function addInstallation({ gitSourceId, installation_id }) {
|
||||
// TODO: We should change installation_id to be camelCase
|
||||
export async function addInstallation({
|
||||
gitSourceId,
|
||||
installation_id
|
||||
}: {
|
||||
gitSourceId: string;
|
||||
installation_id: string;
|
||||
}): Promise<GithubApp> {
|
||||
const source = await prisma.gitSource.findUnique({
|
||||
where: { id: gitSourceId },
|
||||
include: { githubApp: true }
|
||||
@@ -12,8 +20,12 @@ export async function addInstallation({ gitSourceId, installation_id }) {
|
||||
});
|
||||
}
|
||||
|
||||
export async function getUniqueGithubApp({ githubAppId }) {
|
||||
let body = await prisma.githubApp.findUnique({ where: { id: githubAppId } });
|
||||
export async function getUniqueGithubApp({
|
||||
githubAppId
|
||||
}: {
|
||||
githubAppId: string;
|
||||
}): Promise<GithubApp> {
|
||||
const body = await prisma.githubApp.findUnique({ where: { id: githubAppId } });
|
||||
if (body.privateKey) body.privateKey = decrypt(body.privateKey);
|
||||
return body;
|
||||
}
|
||||
@@ -26,7 +38,15 @@ export async function createGithubApp({
|
||||
pem,
|
||||
webhook_secret,
|
||||
state
|
||||
}) {
|
||||
}: {
|
||||
id: number;
|
||||
client_id: string;
|
||||
slug: string;
|
||||
client_secret: string;
|
||||
pem: string;
|
||||
webhook_secret: string;
|
||||
state: string;
|
||||
}): Promise<GithubApp> {
|
||||
const encryptedClientSecret = encrypt(client_secret);
|
||||
const encryptedWebhookSecret = encrypt(webhook_secret);
|
||||
const encryptedPem = encrypt(pem);
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
import { encrypt } from '$lib/crypto';
|
||||
import { generateSshKeyPair, prisma } from './common';
|
||||
import type { GitlabApp } from '@prisma/client';
|
||||
|
||||
export async function updateDeployKey({ id, deployKeyId }) {
|
||||
export async function updateDeployKey({
|
||||
id,
|
||||
deployKeyId
|
||||
}: {
|
||||
id: string;
|
||||
deployKeyId: number;
|
||||
}): Promise<GitlabApp> {
|
||||
const application = await prisma.application.findUnique({
|
||||
where: { id },
|
||||
include: { gitSource: { include: { gitlabApp: true } } }
|
||||
@@ -11,14 +18,24 @@ export async function updateDeployKey({ id, deployKeyId }) {
|
||||
data: { deployKeyId }
|
||||
});
|
||||
}
|
||||
export async function getSshKey({ id }) {
|
||||
export async function getSshKey({
|
||||
id
|
||||
}: {
|
||||
id: string;
|
||||
}): Promise<{ status: number; body: { publicKey: string } }> {
|
||||
const application = await prisma.application.findUnique({
|
||||
where: { id },
|
||||
include: { gitSource: { include: { gitlabApp: true } } }
|
||||
});
|
||||
return { status: 200, body: { publicKey: application.gitSource.gitlabApp.publicSshKey } };
|
||||
}
|
||||
export async function generateSshKey({ id }) {
|
||||
export async function generateSshKey({
|
||||
id
|
||||
}: {
|
||||
id: string;
|
||||
}): Promise<
|
||||
{ status: number; body: { publicKey: string } } | { status: number; body?: undefined }
|
||||
> {
|
||||
const application = await prisma.application.findUnique({
|
||||
where: { id },
|
||||
include: { gitSource: { include: { gitlabApp: true } } }
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
import type { BuildLog } from '@prisma/client';
|
||||
import { prisma, ErrorHandler } from './common';
|
||||
|
||||
export async function listLogs({ buildId, last = 0 }) {
|
||||
export async function listLogs({
|
||||
buildId,
|
||||
last = 0
|
||||
}: {
|
||||
buildId: string;
|
||||
last: number;
|
||||
}): Promise<BuildLog[] | { status: number; body: { message: string; error: string } }> {
|
||||
try {
|
||||
const body = await prisma.buildLog.findMany({
|
||||
where: { buildId, time: { gt: last } },
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { encrypt, decrypt } from '$lib/crypto';
|
||||
import { prisma } from './common';
|
||||
import type { ServiceSecret, Secret, Prisma } from '@prisma/client';
|
||||
|
||||
export async function listServiceSecrets(serviceId: string) {
|
||||
export async function listServiceSecrets(serviceId: string): Promise<ServiceSecret[]> {
|
||||
let secrets = await prisma.serviceSecret.findMany({
|
||||
where: { serviceId },
|
||||
orderBy: { createdAt: 'desc' }
|
||||
@@ -14,7 +15,7 @@ export async function listServiceSecrets(serviceId: string) {
|
||||
return secrets;
|
||||
}
|
||||
|
||||
export async function listSecrets(applicationId: string) {
|
||||
export async function listSecrets(applicationId: string): Promise<Secret[]> {
|
||||
let secrets = await prisma.secret.findMany({
|
||||
where: { applicationId },
|
||||
orderBy: { createdAt: 'desc' }
|
||||
@@ -27,20 +28,48 @@ export async function listSecrets(applicationId: string) {
|
||||
return secrets;
|
||||
}
|
||||
|
||||
export async function createServiceSecret({ id, name, value }) {
|
||||
export async function createServiceSecret({
|
||||
id,
|
||||
name,
|
||||
value
|
||||
}: {
|
||||
id: string;
|
||||
name: string;
|
||||
value: string;
|
||||
}): Promise<ServiceSecret> {
|
||||
value = encrypt(value);
|
||||
return await prisma.serviceSecret.create({
|
||||
data: { name, value, service: { connect: { id } } }
|
||||
});
|
||||
}
|
||||
export async function createSecret({ id, name, value, isBuildSecret, isPRMRSecret }) {
|
||||
export async function createSecret({
|
||||
id,
|
||||
name,
|
||||
value,
|
||||
isBuildSecret,
|
||||
isPRMRSecret
|
||||
}: {
|
||||
id: string;
|
||||
name: string;
|
||||
value: string;
|
||||
isBuildSecret: boolean;
|
||||
isPRMRSecret: boolean;
|
||||
}): Promise<Secret> {
|
||||
value = encrypt(value);
|
||||
return await prisma.secret.create({
|
||||
data: { name, value, isBuildSecret, isPRMRSecret, application: { connect: { id } } }
|
||||
});
|
||||
}
|
||||
|
||||
export async function updateServiceSecret({ id, name, value }) {
|
||||
export async function updateServiceSecret({
|
||||
id,
|
||||
name,
|
||||
value
|
||||
}: {
|
||||
id: string;
|
||||
name: string;
|
||||
value: string;
|
||||
}): Promise<Prisma.BatchPayload | ServiceSecret> {
|
||||
value = encrypt(value);
|
||||
const found = await prisma.serviceSecret.findFirst({ where: { serviceId: id, name } });
|
||||
|
||||
@@ -55,7 +84,19 @@ export async function updateServiceSecret({ id, name, value }) {
|
||||
});
|
||||
}
|
||||
}
|
||||
export async function updateSecret({ id, name, value, isBuildSecret, isPRMRSecret }) {
|
||||
export async function updateSecret({
|
||||
id,
|
||||
name,
|
||||
value,
|
||||
isBuildSecret,
|
||||
isPRMRSecret
|
||||
}: {
|
||||
id: string;
|
||||
name: string;
|
||||
value: string;
|
||||
isBuildSecret: boolean;
|
||||
isPRMRSecret: boolean;
|
||||
}): Promise<Prisma.BatchPayload | Secret> {
|
||||
value = encrypt(value);
|
||||
const found = await prisma.secret.findFirst({ where: { applicationId: id, name, isPRMRSecret } });
|
||||
|
||||
@@ -71,10 +112,22 @@ export async function updateSecret({ id, name, value, isBuildSecret, isPRMRSecre
|
||||
}
|
||||
}
|
||||
|
||||
export async function removeServiceSecret({ id, name }) {
|
||||
export async function removeServiceSecret({
|
||||
id,
|
||||
name
|
||||
}: {
|
||||
id: string;
|
||||
name: string;
|
||||
}): Promise<Prisma.BatchPayload> {
|
||||
return await prisma.serviceSecret.deleteMany({ where: { serviceId: id, name } });
|
||||
}
|
||||
|
||||
export async function removeSecret({ id, name }) {
|
||||
export async function removeSecret({
|
||||
id,
|
||||
name
|
||||
}: {
|
||||
id: string;
|
||||
name: string;
|
||||
}): Promise<Prisma.BatchPayload> {
|
||||
return await prisma.secret.deleteMany({ where: { applicationId: id, name } });
|
||||
}
|
||||
|
||||
@@ -1,10 +1,28 @@
|
||||
import { asyncExecShell, getEngine } from '$lib/common';
|
||||
import { decrypt, encrypt } from '$lib/crypto';
|
||||
import type { Minio, Prisma, Service } from '@prisma/client';
|
||||
import cuid from 'cuid';
|
||||
import { generatePassword } from '.';
|
||||
import { prisma } from './common';
|
||||
|
||||
export async function listServices(teamId) {
|
||||
const include: Prisma.ServiceInclude = {
|
||||
destinationDocker: true,
|
||||
persistentStorage: true,
|
||||
serviceSecret: true,
|
||||
minio: true,
|
||||
plausibleAnalytics: true,
|
||||
vscodeserver: true,
|
||||
wordpress: true,
|
||||
ghost: true,
|
||||
meiliSearch: true,
|
||||
umami: true
|
||||
};
|
||||
export async function listServicesWithIncludes() {
|
||||
return await prisma.service.findMany({
|
||||
include,
|
||||
orderBy: { createdAt: 'desc' }
|
||||
});
|
||||
}
|
||||
export async function listServices(teamId: string): Promise<Service[]> {
|
||||
if (teamId === '0') {
|
||||
return await prisma.service.findMany({ include: { teams: true } });
|
||||
} else {
|
||||
@@ -15,22 +33,18 @@ export async function listServices(teamId) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function newService({ name, teamId }) {
|
||||
export async function newService({
|
||||
name,
|
||||
teamId
|
||||
}: {
|
||||
name: string;
|
||||
teamId: string;
|
||||
}): Promise<Service> {
|
||||
return await prisma.service.create({ data: { name, teams: { connect: { id: teamId } } } });
|
||||
}
|
||||
|
||||
export async function getService({ id, teamId }) {
|
||||
let body = {};
|
||||
const include = {
|
||||
destinationDocker: true,
|
||||
plausibleAnalytics: true,
|
||||
minio: true,
|
||||
vscodeserver: true,
|
||||
wordpress: true,
|
||||
ghost: true,
|
||||
serviceSecret: true,
|
||||
meiliSearch: true
|
||||
};
|
||||
export async function getService({ id, teamId }: { id: string; teamId: string }): Promise<Service> {
|
||||
let body;
|
||||
if (teamId === '0') {
|
||||
body = await prisma.service.findFirst({
|
||||
where: { id },
|
||||
@@ -43,6 +57,12 @@ export async function getService({ id, teamId }) {
|
||||
});
|
||||
}
|
||||
|
||||
if (body?.serviceSecret.length > 0) {
|
||||
body.serviceSecret = body.serviceSecret.map((s) => {
|
||||
s.value = decrypt(s.value);
|
||||
return s;
|
||||
});
|
||||
}
|
||||
if (body.plausibleAnalytics?.postgresqlPassword)
|
||||
body.plausibleAnalytics.postgresqlPassword = decrypt(
|
||||
body.plausibleAnalytics.postgresqlPassword
|
||||
@@ -69,21 +89,26 @@ export async function getService({ id, teamId }) {
|
||||
|
||||
if (body.meiliSearch?.masterKey) body.meiliSearch.masterKey = decrypt(body.meiliSearch.masterKey);
|
||||
|
||||
if (body?.serviceSecret.length > 0) {
|
||||
body.serviceSecret = body.serviceSecret.map((s) => {
|
||||
s.value = decrypt(s.value);
|
||||
return s;
|
||||
});
|
||||
}
|
||||
if (body.wordpress?.ftpPassword) {
|
||||
body.wordpress.ftpPassword = decrypt(body.wordpress.ftpPassword);
|
||||
}
|
||||
if (body.wordpress?.ftpPassword) body.wordpress.ftpPassword = decrypt(body.wordpress.ftpPassword);
|
||||
|
||||
if (body.umami?.postgresqlPassword)
|
||||
body.umami.postgresqlPassword = decrypt(body.umami.postgresqlPassword);
|
||||
if (body.umami?.umamiAdminPassword)
|
||||
body.umami.umamiAdminPassword = decrypt(body.umami.umamiAdminPassword);
|
||||
if (body.umami?.hashSalt) body.umami.hashSalt = decrypt(body.umami.hashSalt);
|
||||
|
||||
const settings = await prisma.setting.findFirst();
|
||||
|
||||
return { ...body, settings };
|
||||
}
|
||||
|
||||
export async function configureServiceType({ id, type }) {
|
||||
export async function configureServiceType({
|
||||
id,
|
||||
type
|
||||
}: {
|
||||
id: string;
|
||||
type: string;
|
||||
}): Promise<void> {
|
||||
if (type === 'plausibleanalytics') {
|
||||
const password = encrypt(generatePassword());
|
||||
const postgresqlUser = cuid();
|
||||
@@ -197,48 +222,184 @@ export async function configureServiceType({ id, type }) {
|
||||
meiliSearch: { create: { masterKey } }
|
||||
}
|
||||
});
|
||||
} else if (type === 'umami') {
|
||||
const umamiAdminPassword = encrypt(generatePassword());
|
||||
const postgresqlUser = cuid();
|
||||
const postgresqlPassword = encrypt(generatePassword());
|
||||
const postgresqlDatabase = 'umami';
|
||||
const hashSalt = encrypt(generatePassword(64));
|
||||
await prisma.service.update({
|
||||
where: { id },
|
||||
data: {
|
||||
type,
|
||||
umami: {
|
||||
create: {
|
||||
umamiAdminPassword,
|
||||
postgresqlDatabase,
|
||||
postgresqlPassword,
|
||||
postgresqlUser,
|
||||
hashSalt
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
export async function setServiceVersion({ id, version }) {
|
||||
|
||||
export async function setServiceVersion({
|
||||
id,
|
||||
version
|
||||
}: {
|
||||
id: string;
|
||||
version: string;
|
||||
}): Promise<Service> {
|
||||
return await prisma.service.update({
|
||||
where: { id },
|
||||
data: { version }
|
||||
});
|
||||
}
|
||||
|
||||
export async function setServiceSettings({ id, dualCerts }) {
|
||||
export async function setServiceSettings({
|
||||
id,
|
||||
dualCerts
|
||||
}: {
|
||||
id: string;
|
||||
dualCerts: boolean;
|
||||
}): Promise<Service> {
|
||||
return await prisma.service.update({
|
||||
where: { id },
|
||||
data: { dualCerts }
|
||||
});
|
||||
}
|
||||
|
||||
export async function updatePlausibleAnalyticsService({ id, fqdn, email, username, name }) {
|
||||
export async function updatePlausibleAnalyticsService({
|
||||
id,
|
||||
fqdn,
|
||||
email,
|
||||
username,
|
||||
name
|
||||
}: {
|
||||
id: string;
|
||||
fqdn: string;
|
||||
name: string;
|
||||
email: string;
|
||||
username: string;
|
||||
}): Promise<void> {
|
||||
await prisma.plausibleAnalytics.update({ where: { serviceId: id }, data: { email, username } });
|
||||
await prisma.service.update({ where: { id }, data: { name, fqdn } });
|
||||
}
|
||||
export async function updateService({ id, fqdn, name }) {
|
||||
|
||||
export async function updateService({
|
||||
id,
|
||||
fqdn,
|
||||
name
|
||||
}: {
|
||||
id: string;
|
||||
fqdn: string;
|
||||
name: string;
|
||||
}): Promise<Service> {
|
||||
return await prisma.service.update({ where: { id }, data: { fqdn, name } });
|
||||
}
|
||||
export async function updateWordpress({ id, fqdn, name, mysqlDatabase, extraConfig }) {
|
||||
|
||||
export async function updateLanguageToolService({
|
||||
id,
|
||||
fqdn,
|
||||
name
|
||||
}: {
|
||||
id: string;
|
||||
fqdn: string;
|
||||
name: string;
|
||||
}): Promise<Service> {
|
||||
return await prisma.service.update({ where: { id }, data: { fqdn, name } });
|
||||
}
|
||||
|
||||
export async function updateMeiliSearchService({
|
||||
id,
|
||||
fqdn,
|
||||
name
|
||||
}: {
|
||||
id: string;
|
||||
fqdn: string;
|
||||
name: string;
|
||||
}): Promise<Service> {
|
||||
return await prisma.service.update({ where: { id }, data: { fqdn, name } });
|
||||
}
|
||||
|
||||
export async function updateVaultWardenService({
|
||||
id,
|
||||
fqdn,
|
||||
name
|
||||
}: {
|
||||
id: string;
|
||||
fqdn: string;
|
||||
name: string;
|
||||
}): Promise<Service> {
|
||||
return await prisma.service.update({ where: { id }, data: { fqdn, name } });
|
||||
}
|
||||
|
||||
export async function updateVsCodeServer({
|
||||
id,
|
||||
fqdn,
|
||||
name
|
||||
}: {
|
||||
id: string;
|
||||
fqdn: string;
|
||||
name: string;
|
||||
}): Promise<Service> {
|
||||
return await prisma.service.update({ where: { id }, data: { fqdn, name } });
|
||||
}
|
||||
|
||||
export async function updateWordpress({
|
||||
id,
|
||||
fqdn,
|
||||
name,
|
||||
mysqlDatabase,
|
||||
extraConfig
|
||||
}: {
|
||||
id: string;
|
||||
fqdn: string;
|
||||
name: string;
|
||||
mysqlDatabase: string;
|
||||
extraConfig: string;
|
||||
}): Promise<Service> {
|
||||
return await prisma.service.update({
|
||||
where: { id },
|
||||
data: { fqdn, name, wordpress: { update: { mysqlDatabase, extraConfig } } }
|
||||
});
|
||||
}
|
||||
export async function updateMinioService({ id, publicPort }) {
|
||||
|
||||
export async function updateMinioService({
|
||||
id,
|
||||
publicPort
|
||||
}: {
|
||||
id: string;
|
||||
publicPort: number;
|
||||
}): Promise<Minio> {
|
||||
return await prisma.minio.update({ where: { serviceId: id }, data: { publicPort } });
|
||||
}
|
||||
export async function updateGhostService({ id, fqdn, name, mariadbDatabase }) {
|
||||
|
||||
export async function updateGhostService({
|
||||
id,
|
||||
fqdn,
|
||||
name,
|
||||
mariadbDatabase
|
||||
}: {
|
||||
id: string;
|
||||
fqdn: string;
|
||||
name: string;
|
||||
mariadbDatabase: string;
|
||||
}): Promise<Service> {
|
||||
return await prisma.service.update({
|
||||
where: { id },
|
||||
data: { fqdn, name, ghost: { update: { mariadbDatabase } } }
|
||||
});
|
||||
}
|
||||
|
||||
export async function removeService({ id }) {
|
||||
export async function removeService({ id }: { id: string }): Promise<void> {
|
||||
await prisma.servicePersistentStorage.deleteMany({ where: { serviceId: id } });
|
||||
await prisma.meiliSearch.deleteMany({ where: { serviceId: id } });
|
||||
await prisma.ghost.deleteMany({ where: { serviceId: id } });
|
||||
await prisma.umami.deleteMany({ where: { serviceId: id } });
|
||||
await prisma.plausibleAnalytics.deleteMany({ where: { serviceId: id } });
|
||||
await prisma.minio.deleteMany({ where: { serviceId: id } });
|
||||
await prisma.vscodeserver.deleteMany({ where: { serviceId: id } });
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { decrypt } from '$lib/crypto';
|
||||
import { prisma } from './common';
|
||||
import type { Setting } from '@prisma/client';
|
||||
|
||||
export async function listSettings() {
|
||||
let settings = await prisma.setting.findFirst({});
|
||||
export async function listSettings(): Promise<Setting> {
|
||||
const settings = await prisma.setting.findFirst({});
|
||||
if (settings.proxyPassword) settings.proxyPassword = decrypt(settings.proxyPassword);
|
||||
return settings;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import type { Team, Permission } from '@prisma/client';
|
||||
import { prisma } from './common';
|
||||
|
||||
export async function listTeams() {
|
||||
export async function listTeams(): Promise<Team[]> {
|
||||
return await prisma.team.findMany();
|
||||
}
|
||||
export async function newTeam({ name, userId }) {
|
||||
export async function newTeam({ name, userId }: { name: string; userId: string }): Promise<Team> {
|
||||
return await prisma.team.create({
|
||||
data: {
|
||||
name,
|
||||
@@ -12,7 +13,11 @@ export async function newTeam({ name, userId }) {
|
||||
}
|
||||
});
|
||||
}
|
||||
export async function getMyTeams({ userId }) {
|
||||
export async function getMyTeams({
|
||||
userId
|
||||
}: {
|
||||
userId: string;
|
||||
}): Promise<(Permission & { team: Team & { _count: { users: number } } })[]> {
|
||||
return await prisma.permission.findMany({
|
||||
where: { userId },
|
||||
include: { team: { include: { _count: { select: { users: true } } } } }
|
||||
|
||||
@@ -1,16 +1,30 @@
|
||||
import cuid from 'cuid';
|
||||
import bcrypt from 'bcrypt';
|
||||
import bcrypt from 'bcryptjs';
|
||||
|
||||
import { prisma } from './common';
|
||||
import { asyncExecShell, uniqueName } from '$lib/common';
|
||||
|
||||
import * as db from '$lib/database';
|
||||
import { startCoolifyProxy } from '$lib/haproxy';
|
||||
export async function hashPassword(password: string) {
|
||||
import type { User } from '@prisma/client';
|
||||
|
||||
export async function hashPassword(password: string): Promise<string> {
|
||||
const saltRounds = 15;
|
||||
return bcrypt.hash(password, saltRounds);
|
||||
}
|
||||
export async function login({ email, password, isLogin }) {
|
||||
|
||||
export async function login({
|
||||
email,
|
||||
password,
|
||||
isLogin
|
||||
}: {
|
||||
email: string;
|
||||
password: string;
|
||||
isLogin: boolean;
|
||||
}): Promise<{
|
||||
status: number;
|
||||
headers: { 'Set-Cookie': string };
|
||||
body: { userId: string; teamId: string; permission: string; isAdmin: boolean };
|
||||
}> {
|
||||
const users = await prisma.user.count();
|
||||
const userFound = await prisma.user.findUnique({
|
||||
where: { email },
|
||||
@@ -32,8 +46,12 @@ export async function login({ email, password, isLogin }) {
|
||||
if (users === 0) {
|
||||
await prisma.setting.update({ where: { id }, data: { isRegistrationEnabled: false } });
|
||||
// Create default network & start Coolify Proxy
|
||||
await asyncExecShell(`docker network create --attachable coolify`);
|
||||
await startCoolifyProxy('/var/run/docker.sock');
|
||||
try {
|
||||
await asyncExecShell(`docker network create --attachable coolify`);
|
||||
} catch (error) {}
|
||||
try {
|
||||
await startCoolifyProxy('/var/run/docker.sock');
|
||||
} catch (error) {}
|
||||
uid = '0';
|
||||
}
|
||||
|
||||
@@ -140,6 +158,6 @@ export async function login({ email, password, isLogin }) {
|
||||
};
|
||||
}
|
||||
|
||||
export async function getUser({ userId }) {
|
||||
export async function getUser({ userId }: { userId: string }): Promise<User> {
|
||||
return await prisma.user.findUnique({ where: { id: userId } });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user