Merge branch 'arm' into improve-typing

This commit is contained in:
Andras Bacsai
2022-04-11 22:39:45 +02:00
committed by GitHub
80 changed files with 1828 additions and 1453 deletions

View File

@@ -26,14 +26,17 @@ export default async function ({
if (secrets.length > 0) {
secrets.forEach((secret) => {
if (secret.isBuildSecret) {
if (pullmergeRequestId) {
if (secret.isPRMRSecret) {
Dockerfile.push(`ARG ${secret.name}=${secret.value}`);
}
} else {
if (!secret.isPRMRSecret) {
Dockerfile.push(`ARG ${secret.name}=${secret.value}`);
}
if (
(pullmergeRequestId && secret.isPRMRSecret) ||
(!pullmergeRequestId && !secret.isPRMRSecret)
) {
Dockerfile.unshift(`ARG ${secret.name}=${secret.value}`);
Dockerfile.forEach((line, index) => {
if (line.startsWith('FROM')) {
Dockerfile.splice(index + 1, 0, `ARG ${secret.name}`);
}
});
}
}
});

View File

@@ -61,12 +61,14 @@ export const saveBuildLog = async ({
buildId: string;
applicationId: string;
}): Promise<Job> => {
if (line.includes('ghs_')) {
const regex = /ghs_.*@/g;
line = line.replace(regex, '<SENSITIVE_DATA_DELETED>@');
if (line) {
if (line.includes('ghs_')) {
const regex = /ghs_.*@/g;
line = line.replace(regex, '<SENSITIVE_DATA_DELETED>@');
}
const addTimestamp = `${generateTimestamp()} ${line}`;
return await buildLogQueue.add(buildId, { buildId, line: addTimestamp, applicationId });
}
const addTimestamp = `${generateTimestamp()} ${line}`;
return await buildLogQueue.add(buildId, { buildId, line: addTimestamp, applicationId });
};
export const getTeam = (event: RequestEvent): string | null => {
@@ -105,6 +107,7 @@ export const getUserDetails = async (
message: 'OK'
}
};
if (isAdminRequired && permission !== 'admin' && permission !== 'owner') {
payload.status = 401;
payload.body.message =

View File

@@ -56,7 +56,7 @@ export const supportedDatabaseTypesAndVersions = [
name: 'postgresql',
fancyName: 'PostgreSQL',
baseImage: 'bitnami/postgresql',
versions: ['14.2', '13.6', '12.10', '11.15', '10.20']
versions: ['14.2.0', '13.6.0', '12.10.0 ', '11.15.0', '10.20.0']
},
{
name: 'redis',

View File

@@ -70,7 +70,11 @@ export async function removeApplication({
await prisma.build.deleteMany({ where: { applicationId: id } });
await prisma.secret.deleteMany({ where: { applicationId: id } });
await prisma.applicationPersistentStorage.deleteMany({ where: { applicationId: id } });
await prisma.application.deleteMany({ where: { id, teams: { some: { id: teamId } } } });
if (teamId === '0') {
await prisma.application.deleteMany({ where: { id } });
} else {
await prisma.application.deleteMany({ where: { id, teams: { some: { id: teamId } } } });
}
}
export async function getApplicationWebhook({

View File

@@ -219,6 +219,7 @@ export function generateDatabaseConfiguration(database: Database & { settings: D
return {
privatePort: 5432,
environmentVariables: {
POSTGRESQL_POSTGRES_PASSWORD: rootUserPassword,
POSTGRESQL_PASSWORD: dbUserPassword,
POSTGRESQL_USERNAME: dbUser,
POSTGRESQL_DATABASE: defaultDatabase

View File

@@ -165,3 +165,43 @@ export async function stopDatabase(
}
return everStarted;
}
export async function updatePasswordInDb(database, user, newPassword, isRoot) {
const {
id,
type,
rootUser,
rootUserPassword,
dbUser,
dbUserPassword,
defaultDatabase,
destinationDockerId,
destinationDocker: { engine }
} = database;
if (destinationDockerId) {
const host = getEngine(engine);
if (type === 'mysql') {
await asyncExecShell(
`DOCKER_HOST=${host} docker exec ${id} mysql -u ${rootUser} -p${rootUserPassword} -e \"ALTER USER '${user}'@'%' IDENTIFIED WITH caching_sha2_password BY '${newPassword}';\"`
);
} else if (type === 'postgresql') {
if (isRoot) {
await asyncExecShell(
`DOCKER_HOST=${host} docker exec ${id} psql postgresql://postgres:${rootUserPassword}@${id}:5432/${defaultDatabase} -c "ALTER role postgres WITH PASSWORD '${newPassword}'"`
);
} else {
await asyncExecShell(
`DOCKER_HOST=${host} docker exec ${id} psql postgresql://${dbUser}:${dbUserPassword}@${id}:5432/${defaultDatabase} -c "ALTER role ${user} WITH PASSWORD '${newPassword}'"`
);
}
} else if (type === 'mongodb') {
await asyncExecShell(
`DOCKER_HOST=${host} docker exec ${id} mongo 'mongodb://${rootUser}:${rootUserPassword}@${id}:27017/admin?readPreference=primary&ssl=false' --eval "db.changeUserPassword('${user}','${newPassword}')"`
);
} else if (type === 'redis') {
await asyncExecShell(
`DOCKER_HOST=${host} docker exec ${id} redis-cli -u redis://${dbUserPassword}@${id}:6379 --raw CONFIG SET requirepass ${newPassword}`
);
}
}
}

View File

@@ -64,9 +64,7 @@ export async function configureDestinationForDatabase({
const host = getEngine(engine);
if (type && version) {
const baseImage = getDatabaseImage(type);
await asyncExecShell(
`DOCKER_HOST=${host} docker pull ${baseImage}:${version} && echo "FROM ${baseImage}:${version}" | docker build --label coolify.image="true" -t "${baseImage}:${version}" -`
);
asyncExecShell(`DOCKER_HOST=${host} docker pull ${baseImage}:${version}`);
}
}
}

View File

@@ -33,17 +33,12 @@ export async function newSource({
}): Promise<GitSource> {
return await prisma.gitSource.create({
data: {
teams: { connect: { id: teamId } },
name,
type,
htmlUrl,
apiUrl,
organization
teams: { connect: { id: teamId } }
}
});
}
export async function removeSource({ id }: { id: string }): Promise<void> {
// TODO: Disconnect application with this sourceId! Maybe not needed?
const source = await prisma.gitSource.delete({
where: { id },
include: { githubApp: true, gitlabApp: true }
@@ -79,22 +74,29 @@ export async function getSource({
if (body?.gitlabApp?.appSecret) body.gitlabApp.appSecret = decrypt(body.gitlabApp.appSecret);
return body;
}
export async function addSource({
export async function addGitHubSource({ id, teamId, type, name, htmlUrl, apiUrl }) {
await prisma.gitSource.update({ where: { id }, data: { type, name, htmlUrl, apiUrl } });
return await prisma.githubApp.create({
data: {
teams: { connect: { id: teamId } },
gitSource: { connect: { id } }
}
});
}
export async function addGitLabSource({
id,
appId,
teamId,
type,
name,
htmlUrl,
apiUrl,
oauthId,
groupName,
appSecret
}: {
id: string;
appId: string;
teamId: string;
oauthId: number;
groupName: string;
appSecret: string;
}): Promise<GitlabApp> {
const encryptedAppSecret = encrypt(appSecret);
appId,
appSecret,
groupName
}) {
const encrptedAppSecret = encrypt(appSecret);
await prisma.gitSource.update({ where: { id }, data: { type, apiUrl, htmlUrl, name } });
return await prisma.gitlabApp.create({
data: {
teams: { connect: { id: teamId } },
@@ -128,6 +130,6 @@ export async function updateGitsource({
}): Promise<GitSource> {
return await prisma.gitSource.update({
where: { id },
data: { name }
data: { name, htmlUrl, apiUrl }
});
}

View File

@@ -177,7 +177,7 @@ export async function configureServiceType({
}
});
} else if (type === 'ghost') {
const defaultEmail = `${cuid()}@coolify.io`;
const defaultEmail = `${cuid()}@example.com`;
const defaultPassword = encrypt(generatePassword());
const mariadbUser = cuid();
const mariadbPassword = encrypt(generatePassword());

View File

@@ -1,5 +1,6 @@
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';
@@ -45,27 +46,43 @@ export async function login({
if (users === 0) {
await prisma.setting.update({ where: { id }, data: { isRegistrationEnabled: false } });
// Create default network & start Coolify Proxy
asyncExecShell(`docker network create --attachable coolify`)
.then(() => {
console.log('Network created');
})
.catch(() => {
console.log('Network already exists.');
});
startCoolifyProxy('/var/run/docker.sock')
.then(() => {
console.log('Coolify Proxy started.');
})
.catch((err) => {
console.log(err);
});
await asyncExecShell(`docker network create --attachable coolify`);
await startCoolifyProxy('/var/run/docker.sock');
uid = '0';
}
if (userFound) {
if (userFound.type === 'email') {
const passwordMatch = bcrypt.compare(password, userFound.password);
if (userFound.password === 'RESETME') {
const hashedPassword = await hashPassword(password);
if (userFound.updatedAt < new Date(Date.now() - 1000 * 60 * 10)) {
await prisma.user.update({
where: { email: userFound.email },
data: { password: 'RESETTIMEOUT' }
});
throw {
error: 'Password reset link has expired. Please request a new one.'
};
} else {
await prisma.user.update({
where: { email: userFound.email },
data: { password: hashedPassword }
});
return {
status: 200,
headers: {
'Set-Cookie': `teamId=${uid}; HttpOnly; Path=/; Max-Age=15778800;`
},
body: {
userId: userFound.id,
teamId: userFound.id,
permission: userFound.permission,
isAdmin: true
}
};
}
}
const passwordMatch = await bcrypt.compare(password, userFound.password);
if (!passwordMatch) {
throw {
error: 'Wrong password or email address.'

View File

@@ -19,7 +19,7 @@ export default async function ({
repodir: string;
privateSshKey: string;
}): Promise<string> {
const url = htmlUrl.replace('https://', '').replace('http://', '');
const url = htmlUrl.replace('https://', '').replace('http://', '').replace(/\/$/, '');
await saveBuildLog({ line: 'GitLab importer started.', buildId, applicationId });
await asyncExecShell(`echo '${privateSshKey}' > ${repodir}/id.rsa`);
await asyncExecShell(`chmod 600 ${repodir}/id.rsa`);

View File

@@ -3,6 +3,7 @@ import { checkContainer, reloadHaproxy } from '$lib/haproxy';
import * as db from '$lib/database';
import { dev } from '$app/env';
import cuid from 'cuid';
import fs from 'fs/promises';
import getPort, { portNumbers } from 'get-port';
import { supportedServiceTypesAndVersions } from '$lib/components/common';
@@ -182,12 +183,41 @@ export async function generateSSLCerts(): Promise<void> {
if (isHttps) ssls.push({ domain, id: 'coolify', isCoolify: true });
}
if (ssls.length > 0) {
const sslDir = dev ? '/tmp/ssl' : '/app/ssl';
if (dev) {
try {
await asyncExecShell(`mkdir -p ${sslDir}`);
} catch (error) {
//
}
}
const files = await fs.readdir(sslDir);
let certificates = [];
if (files.length > 0) {
for (const file of files) {
file.endsWith('.pem') && certificates.push(file.replace(/\.pem$/, ''));
}
}
for (const ssl of ssls) {
if (!dev) {
console.log('Checking SSL for', ssl.domain);
await letsEncrypt(ssl.domain, ssl.id, ssl.isCoolify);
if (
certificates.includes(ssl.domain) ||
certificates.includes(ssl.domain.replace('www.', ''))
) {
console.log(`Certificate for ${ssl.domain} already exists`);
} else {
console.log('Generating SSL for', ssl.domain);
await letsEncrypt(ssl.domain, ssl.id, ssl.isCoolify);
}
} else {
console.log('Checking SSL for', ssl.domain);
if (
certificates.includes(ssl.domain) ||
certificates.includes(ssl.domain.replace('www.', ''))
) {
console.log(`Certificate for ${ssl.domain} already exists`);
} else {
console.log('Generating SSL for', ssl.domain);
}
}
}
}