From ff8037f231f557329fc3151b9f9268ddb29eebaf Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 15 Feb 2022 23:02:03 +0100 Subject: [PATCH 01/35] feat: Generate www & non-www SSL certs --- package.json | 2 +- src/lib/letsencrypt.ts | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 4e84cb3e1..04ed95ea3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "coolify", "description": "An open-source & self-hostable Heroku / Netlify alternative.", - "version": "2.0.12", + "version": "2.0.13", "license": "AGPL-3.0", "scripts": { "dev": "docker compose -f docker-compose-dev.yaml up -d && NODE_ENV=development svelte-kit dev --host 0.0.0.0", diff --git a/src/lib/letsencrypt.ts b/src/lib/letsencrypt.ts index 86d9e6e25..c0a103ca5 100644 --- a/src/lib/letsencrypt.ts +++ b/src/lib/letsencrypt.ts @@ -6,17 +6,19 @@ import cuid from 'cuid'; export async function letsEncrypt({ domain, isCoolify = false, id = null }) { try { + const nakedDomain = domain.replace('www.', ''); + const wwwDomain = `www.${nakedDomain}`; const randomCuid = cuid(); if (dev) { return await forceSSLOnApplication({ domain }); } else { if (isCoolify) { await asyncExecShell( - `docker run --rm --name certbot-${randomCuid} -p 9080:9080 -v "coolify-letsencrypt:/etc/letsencrypt" certbot/certbot --logs-dir /etc/letsencrypt/logs certonly --standalone --preferred-challenges http --http-01-address 0.0.0.0 --http-01-port 9080 -d ${domain} --agree-tos --non-interactive --register-unsafely-without-email` + `docker run --rm --name certbot-${randomCuid} -p 9080:9080 -v "coolify-letsencrypt:/etc/letsencrypt" certbot/certbot --logs-dir /etc/letsencrypt/logs certonly --standalone --preferred-challenges http --http-01-address 0.0.0.0 --http-01-port 9080 -d ${nakedDomain} -d ${wwwDomain} --agree-tos --non-interactive --register-unsafely-without-email` ); const { stderr } = await asyncExecShell( - `docker run --rm -v "coolify-letsencrypt:/etc/letsencrypt" -v "coolify-ssl-certs:/app/ssl" alpine:latest cat /etc/letsencrypt/live/${domain}/fullchain.pem /etc/letsencrypt/live/${domain}/privkey.pem > /app/ssl/${domain}.pem` + `docker run --rm -v "coolify-letsencrypt:/etc/letsencrypt" -v "coolify-ssl-certs:/app/ssl" alpine:latest cat /etc/letsencrypt/live/${nakedDomain}/fullchain.pem /etc/letsencrypt/live/${nakedDomain}/privkey.pem > /app/ssl/${nakedDomain}.pem` ); if (stderr) throw new Error(stderr); return; @@ -35,10 +37,10 @@ export async function letsEncrypt({ domain, isCoolify = false, id = null }) { if (data.destinationDockerId && data.destinationDocker) { const host = getEngine(data.destinationDocker.engine); await asyncExecShell( - `DOCKER_HOST=${host} docker run --rm --name certbot-${randomCuid} -p 9080:9080 -v "coolify-letsencrypt:/etc/letsencrypt" certbot/certbot --logs-dir /etc/letsencrypt/logs certonly --standalone --preferred-challenges http --http-01-address 0.0.0.0 --http-01-port 9080 -d ${domain} --agree-tos --non-interactive --register-unsafely-without-email` + `DOCKER_HOST=${host} docker run --rm --name certbot-${randomCuid} -p 9080:9080 -v "coolify-letsencrypt:/etc/letsencrypt" certbot/certbot --logs-dir /etc/letsencrypt/logs certonly --standalone --preferred-challenges http --http-01-address 0.0.0.0 --http-01-port 9080 -d ${nakedDomain} -d ${wwwDomain} --agree-tos --non-interactive --register-unsafely-without-email` ); const { stderr } = await asyncExecShell( - `DOCKER_HOST=${host} docker run --rm --name bash-${randomCuid} -v "coolify-letsencrypt:/etc/letsencrypt" -v "coolify-ssl-certs:/app/ssl" alpine:latest cat /etc/letsencrypt/live/${domain}/fullchain.pem /etc/letsencrypt/live/${domain}/privkey.pem > /app/ssl/${domain}.pem` + `DOCKER_HOST=${host} docker run --rm --name bash-${randomCuid} -v "coolify-letsencrypt:/etc/letsencrypt" -v "coolify-ssl-certs:/app/ssl" alpine:latest cat /etc/letsencrypt/live/${nakedDomain}/fullchain.pem /etc/letsencrypt/live/${nakedDomain}/privkey.pem > /app/ssl/${nakedDomain}.pem` ); if (stderr) throw new Error(stderr); await forceSSLOnApplication({ domain }); From 2f0e4587659bdf4e54c19492d11ac14780eaaabd Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 15 Feb 2022 23:12:28 +0100 Subject: [PATCH 02/35] Expand flag for lets encrypt --- src/lib/letsencrypt.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/letsencrypt.ts b/src/lib/letsencrypt.ts index c0a103ca5..9465ec8da 100644 --- a/src/lib/letsencrypt.ts +++ b/src/lib/letsencrypt.ts @@ -14,7 +14,7 @@ export async function letsEncrypt({ domain, isCoolify = false, id = null }) { } else { if (isCoolify) { await asyncExecShell( - `docker run --rm --name certbot-${randomCuid} -p 9080:9080 -v "coolify-letsencrypt:/etc/letsencrypt" certbot/certbot --logs-dir /etc/letsencrypt/logs certonly --standalone --preferred-challenges http --http-01-address 0.0.0.0 --http-01-port 9080 -d ${nakedDomain} -d ${wwwDomain} --agree-tos --non-interactive --register-unsafely-without-email` + `docker run --rm --name certbot-${randomCuid} -p 9080:9080 -v "coolify-letsencrypt:/etc/letsencrypt" certbot/certbot --logs-dir /etc/letsencrypt/logs certonly --standalone --preferred-challenges http --http-01-address 0.0.0.0 --http-01-port 9080 -d ${nakedDomain} -d ${wwwDomain} --expand --agree-tos --non-interactive --register-unsafely-without-email` ); const { stderr } = await asyncExecShell( @@ -37,7 +37,7 @@ export async function letsEncrypt({ domain, isCoolify = false, id = null }) { if (data.destinationDockerId && data.destinationDocker) { const host = getEngine(data.destinationDocker.engine); await asyncExecShell( - `DOCKER_HOST=${host} docker run --rm --name certbot-${randomCuid} -p 9080:9080 -v "coolify-letsencrypt:/etc/letsencrypt" certbot/certbot --logs-dir /etc/letsencrypt/logs certonly --standalone --preferred-challenges http --http-01-address 0.0.0.0 --http-01-port 9080 -d ${nakedDomain} -d ${wwwDomain} --agree-tos --non-interactive --register-unsafely-without-email` + `DOCKER_HOST=${host} docker run --rm --name certbot-${randomCuid} -p 9080:9080 -v "coolify-letsencrypt:/etc/letsencrypt" certbot/certbot --logs-dir /etc/letsencrypt/logs certonly --standalone --preferred-challenges http --http-01-address 0.0.0.0 --http-01-port 9080 -d ${nakedDomain} -d ${wwwDomain} --expand --agree-tos --non-interactive --register-unsafely-without-email` ); const { stderr } = await asyncExecShell( `DOCKER_HOST=${host} docker run --rm --name bash-${randomCuid} -v "coolify-letsencrypt:/etc/letsencrypt" -v "coolify-ssl-certs:/app/ssl" alpine:latest cat /etc/letsencrypt/live/${nakedDomain}/fullchain.pem /etc/letsencrypt/live/${nakedDomain}/privkey.pem > /app/ssl/${nakedDomain}.pem` From eabaca145e2494d7c8636b3babeb5c2c2b9dea42 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 15 Feb 2022 23:38:10 +0100 Subject: [PATCH 03/35] Fix --- src/lib/letsencrypt.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/lib/letsencrypt.ts b/src/lib/letsencrypt.ts index 9465ec8da..27b3a7eea 100644 --- a/src/lib/letsencrypt.ts +++ b/src/lib/letsencrypt.ts @@ -13,14 +13,15 @@ export async function letsEncrypt({ domain, isCoolify = false, id = null }) { return await forceSSLOnApplication({ domain }); } else { if (isCoolify) { - await asyncExecShell( + const { stderr: certError } = await asyncExecShell( `docker run --rm --name certbot-${randomCuid} -p 9080:9080 -v "coolify-letsencrypt:/etc/letsencrypt" certbot/certbot --logs-dir /etc/letsencrypt/logs certonly --standalone --preferred-challenges http --http-01-address 0.0.0.0 --http-01-port 9080 -d ${nakedDomain} -d ${wwwDomain} --expand --agree-tos --non-interactive --register-unsafely-without-email` ); + if (certError) throw new Error(certError); - const { stderr } = await asyncExecShell( - `docker run --rm -v "coolify-letsencrypt:/etc/letsencrypt" -v "coolify-ssl-certs:/app/ssl" alpine:latest cat /etc/letsencrypt/live/${nakedDomain}/fullchain.pem /etc/letsencrypt/live/${nakedDomain}/privkey.pem > /app/ssl/${nakedDomain}.pem` + const { stderr: copyError } = await asyncExecShell( + `docker run --rm -v "coolify-letsencrypt:/etc/letsencrypt" -v "coolify-ssl-certs:/app/ssl" alpine:latest sh -c "test -d /etc/letsencrypt/live/${nakedDomain}/ && cat /etc/letsencrypt/live/${nakedDomain}/fullchain.pem /etc/letsencrypt/live/${nakedDomain}/privkey.pem > /app/ssl/${nakedDomain}.pem || cat /etc/letsencrypt/live/${wwwDomain}/fullchain.pem /etc/letsencrypt/live/${wwwDomain}/privkey.pem > /app/ssl/${wwwDomain}.pem"` ); - if (stderr) throw new Error(stderr); + if (copyError) throw new Error(copyError); return; } let data: any = await db.prisma.application.findUnique({ @@ -36,13 +37,14 @@ export async function letsEncrypt({ domain, isCoolify = false, id = null }) { // Set SSL with Let's encrypt if (data.destinationDockerId && data.destinationDocker) { const host = getEngine(data.destinationDocker.engine); - await asyncExecShell( + const { stderr: certError } = await asyncExecShell( `DOCKER_HOST=${host} docker run --rm --name certbot-${randomCuid} -p 9080:9080 -v "coolify-letsencrypt:/etc/letsencrypt" certbot/certbot --logs-dir /etc/letsencrypt/logs certonly --standalone --preferred-challenges http --http-01-address 0.0.0.0 --http-01-port 9080 -d ${nakedDomain} -d ${wwwDomain} --expand --agree-tos --non-interactive --register-unsafely-without-email` ); - const { stderr } = await asyncExecShell( - `DOCKER_HOST=${host} docker run --rm --name bash-${randomCuid} -v "coolify-letsencrypt:/etc/letsencrypt" -v "coolify-ssl-certs:/app/ssl" alpine:latest cat /etc/letsencrypt/live/${nakedDomain}/fullchain.pem /etc/letsencrypt/live/${nakedDomain}/privkey.pem > /app/ssl/${nakedDomain}.pem` + if (certError) throw new Error(certError); + const { stderr: copyError } = await asyncExecShell( + `DOCKER_HOST=${host} docker run --rm -v "coolify-letsencrypt:/etc/letsencrypt" -v "coolify-ssl-certs:/app/ssl" alpine:latest sh -c "test -d /etc/letsencrypt/live/${nakedDomain}/ && cat /etc/letsencrypt/live/${nakedDomain}/fullchain.pem /etc/letsencrypt/live/${nakedDomain}/privkey.pem > /app/ssl/${nakedDomain}.pem || cat /etc/letsencrypt/live/${wwwDomain}/fullchain.pem /etc/letsencrypt/live/${wwwDomain}/privkey.pem > /app/ssl/${wwwDomain}.pem"` ); - if (stderr) throw new Error(stderr); + if (copyError) throw new Error(copyError); await forceSSLOnApplication({ domain }); } } From df25a694c3d31efc3248fee7ecc902f680c55784 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 15 Feb 2022 23:59:26 +0100 Subject: [PATCH 04/35] fix: Add no user redis to uri --- src/routes/databases/[id]/_Databases/_Databases.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/databases/[id]/_Databases/_Databases.svelte b/src/routes/databases/[id]/_Databases/_Databases.svelte index 1483cab1b..cd91c8d6a 100644 --- a/src/routes/databases/[id]/_Databases/_Databases.svelte +++ b/src/routes/databases/[id]/_Databases/_Databases.svelte @@ -36,7 +36,7 @@ function generateUrl() { return browser - ? `${database.type}://${ + ? `${database.type}://${database.type === 'redis' && ':'}${ databaseDbUser ? databaseDbUser + ':' : '' }${databaseDbUserPassword}@${ isPublic From 91849cdd3a5612c6cd81088884845efda790c871 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 16 Feb 2022 00:00:49 +0100 Subject: [PATCH 05/35] fix www - non-www ssl --- src/lib/letsencrypt.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/lib/letsencrypt.ts b/src/lib/letsencrypt.ts index 27b3a7eea..6e166d8f2 100644 --- a/src/lib/letsencrypt.ts +++ b/src/lib/letsencrypt.ts @@ -1,5 +1,5 @@ import { dev } from '$app/env'; -import { forceSSLOffApplication, forceSSLOnApplication, getNextTransactionId } from '$lib/haproxy'; +import { forceSSLOnApplication } from '$lib/haproxy'; import { asyncExecShell, getEngine } from './common'; import * as db from '$lib/database'; import cuid from 'cuid'; @@ -13,15 +13,15 @@ export async function letsEncrypt({ domain, isCoolify = false, id = null }) { return await forceSSLOnApplication({ domain }); } else { if (isCoolify) { - const { stderr: certError } = await asyncExecShell( + await asyncExecShell( `docker run --rm --name certbot-${randomCuid} -p 9080:9080 -v "coolify-letsencrypt:/etc/letsencrypt" certbot/certbot --logs-dir /etc/letsencrypt/logs certonly --standalone --preferred-challenges http --http-01-address 0.0.0.0 --http-01-port 9080 -d ${nakedDomain} -d ${wwwDomain} --expand --agree-tos --non-interactive --register-unsafely-without-email` ); - if (certError) throw new Error(certError); const { stderr: copyError } = await asyncExecShell( `docker run --rm -v "coolify-letsencrypt:/etc/letsencrypt" -v "coolify-ssl-certs:/app/ssl" alpine:latest sh -c "test -d /etc/letsencrypt/live/${nakedDomain}/ && cat /etc/letsencrypt/live/${nakedDomain}/fullchain.pem /etc/letsencrypt/live/${nakedDomain}/privkey.pem > /app/ssl/${nakedDomain}.pem || cat /etc/letsencrypt/live/${wwwDomain}/fullchain.pem /etc/letsencrypt/live/${wwwDomain}/privkey.pem > /app/ssl/${wwwDomain}.pem"` ); - if (copyError) throw new Error(copyError); + + if (copyError) throw copyError; return; } let data: any = await db.prisma.application.findUnique({ @@ -37,18 +37,18 @@ export async function letsEncrypt({ domain, isCoolify = false, id = null }) { // Set SSL with Let's encrypt if (data.destinationDockerId && data.destinationDocker) { const host = getEngine(data.destinationDocker.engine); - const { stderr: certError } = await asyncExecShell( + await asyncExecShell( `DOCKER_HOST=${host} docker run --rm --name certbot-${randomCuid} -p 9080:9080 -v "coolify-letsencrypt:/etc/letsencrypt" certbot/certbot --logs-dir /etc/letsencrypt/logs certonly --standalone --preferred-challenges http --http-01-address 0.0.0.0 --http-01-port 9080 -d ${nakedDomain} -d ${wwwDomain} --expand --agree-tos --non-interactive --register-unsafely-without-email` ); - if (certError) throw new Error(certError); const { stderr: copyError } = await asyncExecShell( `DOCKER_HOST=${host} docker run --rm -v "coolify-letsencrypt:/etc/letsencrypt" -v "coolify-ssl-certs:/app/ssl" alpine:latest sh -c "test -d /etc/letsencrypt/live/${nakedDomain}/ && cat /etc/letsencrypt/live/${nakedDomain}/fullchain.pem /etc/letsencrypt/live/${nakedDomain}/privkey.pem > /app/ssl/${nakedDomain}.pem || cat /etc/letsencrypt/live/${wwwDomain}/fullchain.pem /etc/letsencrypt/live/${wwwDomain}/privkey.pem > /app/ssl/${wwwDomain}.pem"` ); - if (copyError) throw new Error(copyError); + if (copyError) throw copyError; await forceSSLOnApplication({ domain }); } } } catch (error) { + console.log(error); throw error; } } From 655d0b5d5f0ff8839fd506258026502499a7fc48 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 16 Feb 2022 17:13:24 +0100 Subject: [PATCH 06/35] fix: Secure cookie disabled by default --- src/hooks.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hooks.ts b/src/hooks.ts index d4fea1baf..7a9208585 100644 --- a/src/hooks.ts +++ b/src/hooks.ts @@ -10,7 +10,8 @@ import { dev } from '$app/env'; export const handle = handleSession( { secret: process.env['COOLIFY_SECRET_KEY'], - expires: 30 + expires: 30, + cookie: { secure: false } }, async function ({ event, resolve }) { let response; From 8b20761e8b1e1c2d7954275e705b01d5dc319aa0 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 17 Feb 2022 10:11:46 +0100 Subject: [PATCH 07/35] fix: Buggy svelte-kit-cookie-session --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 04ed95ea3..e03c678b0 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "js-yaml": "4.1.0", "jsonwebtoken": "8.5.1", "node-forge": "1.2.1", - "svelte-kit-cookie-session": "2.0.5", + "svelte-kit-cookie-session": "2.0.2", "unique-names-generator": "4.6.0" }, "prisma": { From bf047e2a3ceea5c674322a3b1507438a4ee87d15 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 17 Feb 2022 22:14:06 +0100 Subject: [PATCH 08/35] feat: Dual certificates desing: Lots of design/css updates version++ --- package.json | 3 +- pnpm-lock.yaml | 21 ++- .../20220217211304_dualcerts/migration.sql | 47 +++++++ prisma/schema.prisma | 5 +- src/lib/components/Explainer.svelte | 4 +- src/lib/components/Setting.svelte | 13 +- src/lib/database/applications.ts | 4 +- src/lib/database/services.ts | 9 +- src/lib/haproxy/index.ts | 1 - src/lib/letsencrypt.ts | 73 ++++++---- src/routes/applications/[id]/index.svelte | 35 +++-- src/routes/applications/[id]/settings.json.ts | 4 +- .../databases/[id]/_Databases/_CouchDb.svelte | 106 +++++++-------- .../[id]/_Databases/_Databases.svelte | 126 ++++++++---------- .../databases/[id]/_Databases/_MongoDB.svelte | 42 +++--- .../databases/[id]/_Databases/_MySQL.svelte | 106 +++++++-------- .../[id]/_Databases/_PostgreSQL.svelte | 64 ++++----- .../databases/[id]/_Databases/_Redis.svelte | 35 ++--- .../destinations/[id]/_LocalDocker.svelte | 27 ++-- .../services/[id]/_Services/_MinIO.svelte | 60 ++++----- .../[id]/_Services/_PlausibleAnalytics.svelte | 120 ++++++++--------- .../services/[id]/_Services/_Services.svelte | 35 ++++- .../[id]/_Services/_VSCodeServer.svelte | 20 ++- .../services/[id]/_Services/_Wordpress.svelte | 114 +++++++--------- .../[id]/configuration/version.json.ts | 2 +- src/routes/services/[id]/settings.json.ts | 19 +++ src/routes/settings/index.json.ts | 19 ++- src/routes/settings/index.svelte | 108 ++++++++------- src/routes/sources/[id]/_Gitlab.svelte | 2 +- src/routes/teams/[id]/index.svelte | 24 ++-- src/tailwind.css | 6 +- tailwind.config.cjs | 3 +- 32 files changed, 670 insertions(+), 587 deletions(-) create mode 100644 prisma/migrations/20220217211304_dualcerts/migration.sql create mode 100644 src/routes/services/[id]/settings.json.ts diff --git a/package.json b/package.json index e03c678b0..50dba74e9 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "coolify", "description": "An open-source & self-hostable Heroku / Netlify alternative.", - "version": "2.0.13", + "version": "2.0.14", "license": "AGPL-3.0", "scripts": { "dev": "docker compose -f docker-compose-dev.yaml up -d && NODE_ENV=development svelte-kit dev --host 0.0.0.0", @@ -76,6 +76,7 @@ "jsonwebtoken": "8.5.1", "node-forge": "1.2.1", "svelte-kit-cookie-session": "2.0.2", + "tailwindcss-scrollbar": "^0.1.0", "unique-names-generator": "4.6.0" }, "prisma": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 58ddfd8c6..b6e75d0bc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -43,9 +43,10 @@ specifiers: prisma: 3.9.2 svelte: 3.46.4 svelte-check: 2.4.3 - svelte-kit-cookie-session: 2.0.5 + svelte-kit-cookie-session: 2.0.2 svelte-preprocess: 4.10.3 tailwindcss: 3.0.22 + tailwindcss-scrollbar: ^0.1.0 ts-node: 10.5.0 tslib: 2.3.1 typescript: 4.5.5 @@ -70,7 +71,8 @@ dependencies: js-yaml: 4.1.0 jsonwebtoken: 8.5.1 node-forge: 1.2.1 - svelte-kit-cookie-session: 2.0.5 + svelte-kit-cookie-session: 2.0.2 + tailwindcss-scrollbar: 0.1.0_tailwindcss@3.0.22 unique-names-generator: 4.6.0 devDependencies: @@ -5203,10 +5205,10 @@ packages: svelte: 3.46.4 dev: true - /svelte-kit-cookie-session/2.0.5: + /svelte-kit-cookie-session/2.0.2: resolution: { - integrity: sha512-IX1IXtn42UTz/isem1LqH0SAZdCx6Z6Iu2V4Q83V2EScFbXZWfeFY08Azl8ZrPKdIDhSNHBLAAumRjA6TBxCvQ== + integrity: sha512-+JfunYbraIOkecOJlC1iYqH9g6YOY8MXyUdE3hTZquR1JrODmOZZ+pVPmZuVIFpM5sStJf/jF1NT5306TWE9Gw== } dev: false @@ -5288,6 +5290,17 @@ packages: strip-ansi: 6.0.1 dev: true + /tailwindcss-scrollbar/0.1.0_tailwindcss@3.0.22: + resolution: + { + integrity: sha512-egipxw4ooQDh94x02XQpPck0P0sfwazwoUGfA9SedPATIuYDR+6qe8d31Gl7YsSMRiOKDkkqfI0kBvEw9lT/Hg== + } + peerDependencies: + tailwindcss: '>= 2.x.x' + dependencies: + tailwindcss: 3.0.22_c940fbabf228b85b1c73d314b43e31f1 + dev: false + /tailwindcss/3.0.22_c940fbabf228b85b1c73d314b43e31f1: resolution: { diff --git a/prisma/migrations/20220217211304_dualcerts/migration.sql b/prisma/migrations/20220217211304_dualcerts/migration.sql new file mode 100644 index 000000000..a6ea0a57d --- /dev/null +++ b/prisma/migrations/20220217211304_dualcerts/migration.sql @@ -0,0 +1,47 @@ +-- RedefineTables +PRAGMA foreign_keys=OFF; +CREATE TABLE "new_Setting" ( + "id" TEXT NOT NULL PRIMARY KEY, + "fqdn" TEXT, + "isRegistrationEnabled" BOOLEAN NOT NULL DEFAULT false, + "dualCerts" BOOLEAN NOT NULL DEFAULT false, + "proxyPassword" TEXT NOT NULL, + "proxyUser" TEXT NOT NULL, + "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" DATETIME NOT NULL +); +INSERT INTO "new_Setting" ("createdAt", "fqdn", "id", "isRegistrationEnabled", "proxyPassword", "proxyUser", "updatedAt") SELECT "createdAt", "fqdn", "id", "isRegistrationEnabled", "proxyPassword", "proxyUser", "updatedAt" FROM "Setting"; +DROP TABLE "Setting"; +ALTER TABLE "new_Setting" RENAME TO "Setting"; +CREATE UNIQUE INDEX "Setting_fqdn_key" ON "Setting"("fqdn"); +CREATE TABLE "new_ApplicationSettings" ( + "id" TEXT NOT NULL PRIMARY KEY, + "applicationId" TEXT NOT NULL, + "dualCerts" BOOLEAN NOT NULL DEFAULT false, + "debug" BOOLEAN NOT NULL DEFAULT false, + "previews" BOOLEAN NOT NULL DEFAULT false, + "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" DATETIME NOT NULL, + CONSTRAINT "ApplicationSettings_applicationId_fkey" FOREIGN KEY ("applicationId") REFERENCES "Application" ("id") ON DELETE RESTRICT ON UPDATE CASCADE +); +INSERT INTO "new_ApplicationSettings" ("applicationId", "createdAt", "debug", "id", "previews", "updatedAt") SELECT "applicationId", "createdAt", "debug", "id", "previews", "updatedAt" FROM "ApplicationSettings"; +DROP TABLE "ApplicationSettings"; +ALTER TABLE "new_ApplicationSettings" RENAME TO "ApplicationSettings"; +CREATE UNIQUE INDEX "ApplicationSettings_applicationId_key" ON "ApplicationSettings"("applicationId"); +CREATE TABLE "new_Service" ( + "id" TEXT NOT NULL PRIMARY KEY, + "name" TEXT NOT NULL, + "fqdn" TEXT, + "dualCerts" BOOLEAN NOT NULL DEFAULT false, + "type" TEXT, + "version" TEXT, + "destinationDockerId" TEXT, + "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" DATETIME NOT NULL, + CONSTRAINT "Service_destinationDockerId_fkey" FOREIGN KEY ("destinationDockerId") REFERENCES "DestinationDocker" ("id") ON DELETE SET NULL ON UPDATE CASCADE +); +INSERT INTO "new_Service" ("createdAt", "destinationDockerId", "fqdn", "id", "name", "type", "updatedAt", "version") SELECT "createdAt", "destinationDockerId", "fqdn", "id", "name", "type", "updatedAt", "version" FROM "Service"; +DROP TABLE "Service"; +ALTER TABLE "new_Service" RENAME TO "Service"; +PRAGMA foreign_key_check; +PRAGMA foreign_keys=ON; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index b064d09ab..cf9684f53 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -11,6 +11,7 @@ model Setting { id String @id @default(cuid()) fqdn String? @unique isRegistrationEnabled Boolean @default(false) + dualCerts Boolean @default(false) proxyPassword String proxyUser String createdAt DateTime @default(now()) @@ -97,6 +98,7 @@ model ApplicationSettings { id String @id @default(cuid()) application Application @relation(fields: [applicationId], references: [id]) applicationId String @unique + dualCerts Boolean @default(false) debug Boolean @default(false) previews Boolean @default(false) createdAt DateTime @default(now()) @@ -105,7 +107,7 @@ model ApplicationSettings { model Secret { id String @id @default(cuid()) - name String + name String value String isBuildSecret Boolean @default(false) createdAt DateTime @default(now()) @@ -234,6 +236,7 @@ model Service { id String @id @default(cuid()) name String fqdn String? + dualCerts Boolean @default(false) type String? version String? teams Team[] diff --git a/src/lib/components/Explainer.svelte b/src/lib/components/Explainer.svelte index 4eaf3a398..b47c03ec1 100644 --- a/src/lib/components/Explainer.svelte +++ b/src/lib/components/Explainer.svelte @@ -1,6 +1,6 @@ -
{@html text}
+
{@html text}
diff --git a/src/lib/components/Setting.svelte b/src/lib/components/Setting.svelte index b26e3e072..c431273e6 100644 --- a/src/lib/components/Setting.svelte +++ b/src/lib/components/Setting.svelte @@ -4,15 +4,17 @@ export let setting; export let title; export let description; - export let isPadding = true; + export let isCenter = true; export let disabled = false; -
  • -
    -

    {title}

    +
    +
    +
    {title}
    +
    +
    - -
  • + diff --git a/src/lib/database/applications.ts b/src/lib/database/applications.ts index 738ebe594..f2e779bee 100644 --- a/src/lib/database/applications.ts +++ b/src/lib/database/applications.ts @@ -209,10 +209,10 @@ export async function configureApplication({ }); } -export async function setApplicationSettings({ id, debug, previews }) { +export async function setApplicationSettings({ id, debug, previews, dualCerts }) { return await prisma.application.update({ where: { id }, - data: { settings: { update: { debug, previews } } }, + data: { settings: { update: { debug, previews, dualCerts } } }, include: { destinationDocker: true } }); } diff --git a/src/lib/database/services.ts b/src/lib/database/services.ts index 5568cd4a7..5cbf2cbfb 100644 --- a/src/lib/database/services.ts +++ b/src/lib/database/services.ts @@ -107,13 +107,20 @@ export async function configureServiceType({ id, type }) { }); } } -export async function setService({ id, version }) { +export async function setServiceVersion({ id, version }) { return await prisma.service.update({ where: { id }, data: { version } }); } +export async function setServiceSettings({ id, dualCerts }) { + return await prisma.service.update({ + where: { id }, + data: { dualCerts } + }); +} + export async function updatePlausibleAnalyticsService({ id, fqdn, email, username, name }) { await prisma.plausibleAnalytics.update({ where: { serviceId: id }, data: { email, username } }); await prisma.service.update({ where: { id }, data: { name, fqdn } }); diff --git a/src/lib/haproxy/index.ts b/src/lib/haproxy/index.ts index 0eaee0109..0daf1d493 100644 --- a/src/lib/haproxy/index.ts +++ b/src/lib/haproxy/index.ts @@ -2,7 +2,6 @@ import { dev } from '$app/env'; import { asyncExecShell, getDomain, getEngine } from '$lib/common'; import got from 'got'; import * as db from '$lib/database'; -import { letsEncrypt } from '$lib/letsencrypt'; const url = dev ? 'http://localhost:5555' : 'http://coolify-haproxy:5555'; diff --git a/src/lib/letsencrypt.ts b/src/lib/letsencrypt.ts index 6e166d8f2..6ee29f812 100644 --- a/src/lib/letsencrypt.ts +++ b/src/lib/letsencrypt.ts @@ -3,49 +3,70 @@ import { forceSSLOnApplication } from '$lib/haproxy'; import { asyncExecShell, getEngine } from './common'; import * as db from '$lib/database'; import cuid from 'cuid'; +import getPort from 'get-port'; export async function letsEncrypt({ domain, isCoolify = false, id = null }) { try { const nakedDomain = domain.replace('www.', ''); const wwwDomain = `www.${nakedDomain}`; const randomCuid = cuid(); - if (dev) { - return await forceSSLOnApplication({ domain }); + const randomPort = getPort(); + + let host; + let dualCerts = false; + if (isCoolify) { + const data = await db.prisma.setting.findFirst(); + dualCerts = data.dualCerts; + host = '/var/run/docker.sock'; } else { - if (isCoolify) { - await asyncExecShell( - `docker run --rm --name certbot-${randomCuid} -p 9080:9080 -v "coolify-letsencrypt:/etc/letsencrypt" certbot/certbot --logs-dir /etc/letsencrypt/logs certonly --standalone --preferred-challenges http --http-01-address 0.0.0.0 --http-01-port 9080 -d ${nakedDomain} -d ${wwwDomain} --expand --agree-tos --non-interactive --register-unsafely-without-email` - ); - - const { stderr: copyError } = await asyncExecShell( - `docker run --rm -v "coolify-letsencrypt:/etc/letsencrypt" -v "coolify-ssl-certs:/app/ssl" alpine:latest sh -c "test -d /etc/letsencrypt/live/${nakedDomain}/ && cat /etc/letsencrypt/live/${nakedDomain}/fullchain.pem /etc/letsencrypt/live/${nakedDomain}/privkey.pem > /app/ssl/${nakedDomain}.pem || cat /etc/letsencrypt/live/${wwwDomain}/fullchain.pem /etc/letsencrypt/live/${wwwDomain}/privkey.pem > /app/ssl/${wwwDomain}.pem"` - ); - - if (copyError) throw copyError; - return; + // Check Application + const applicationData = await db.prisma.application.findUnique({ + where: { id }, + include: { destinationDocker: true, settings: true } + }); + if (applicationData) { + if (applicationData?.destinationDockerId && applicationData?.destinationDocker) { + host = getEngine(applicationData.destinationDocker.engine); + } + if (applicationData?.settings?.dualCerts) { + dualCerts = applicationData.settings.dualCerts; + } } - let data: any = await db.prisma.application.findUnique({ + // Check Service + const serviceData = await db.prisma.service.findUnique({ where: { id }, include: { destinationDocker: true } }); - if (!data) { - data = await db.prisma.service.findUnique({ - where: { id }, - include: { destinationDocker: true } - }); + if (serviceData) { + if (serviceData?.destinationDockerId && serviceData?.destinationDocker) { + host = getEngine(serviceData.destinationDocker.engine); + } + if (serviceData?.dualCerts) { + dualCerts = serviceData.dualCerts; + } } - // Set SSL with Let's encrypt - if (data.destinationDockerId && data.destinationDocker) { - const host = getEngine(data.destinationDocker.engine); + } + if (!dev) { + if (dualCerts) { await asyncExecShell( - `DOCKER_HOST=${host} docker run --rm --name certbot-${randomCuid} -p 9080:9080 -v "coolify-letsencrypt:/etc/letsencrypt" certbot/certbot --logs-dir /etc/letsencrypt/logs certonly --standalone --preferred-challenges http --http-01-address 0.0.0.0 --http-01-port 9080 -d ${nakedDomain} -d ${wwwDomain} --expand --agree-tos --non-interactive --register-unsafely-without-email` + `DOCKER_HOST=${host} docker run --rm --name certbot-${randomCuid} -p ${randomPort}:${randomPort} -v "coolify-letsencrypt:/etc/letsencrypt" certbot/certbot --logs-dir /etc/letsencrypt/logs certonly --standalone --preferred-challenges http --http-01-address 0.0.0.0 --http-01-port ${randomPort} -d ${nakedDomain} -d ${wwwDomain} --expand --agree-tos --non-interactive --register-unsafely-without-email` ); - const { stderr: copyError } = await asyncExecShell( + await asyncExecShell( `DOCKER_HOST=${host} docker run --rm -v "coolify-letsencrypt:/etc/letsencrypt" -v "coolify-ssl-certs:/app/ssl" alpine:latest sh -c "test -d /etc/letsencrypt/live/${nakedDomain}/ && cat /etc/letsencrypt/live/${nakedDomain}/fullchain.pem /etc/letsencrypt/live/${nakedDomain}/privkey.pem > /app/ssl/${nakedDomain}.pem || cat /etc/letsencrypt/live/${wwwDomain}/fullchain.pem /etc/letsencrypt/live/${wwwDomain}/privkey.pem > /app/ssl/${wwwDomain}.pem"` ); - if (copyError) throw copyError; - await forceSSLOnApplication({ domain }); + } else { + await asyncExecShell( + `DOCKER_HOST=${host} docker run --rm --name certbot-${randomCuid} -p ${randomPort}:${randomPort} -v "coolify-letsencrypt:/etc/letsencrypt" certbot/certbot --logs-dir /etc/letsencrypt/logs certonly --standalone --preferred-challenges http --http-01-address 0.0.0.0 --http-01-port ${randomPort} -d ${domain} --expand --agree-tos --non-interactive --register-unsafely-without-email` + ); + await asyncExecShell( + `DOCKER_HOST=${host} docker run --rm -v "coolify-letsencrypt:/etc/letsencrypt" -v "coolify-ssl-certs:/app/ssl" alpine:latest sh -c "cat /etc/letsencrypt/live/${domain}/fullchain.pem /etc/letsencrypt/live/${domain}/privkey.pem > /app/ssl/${domain}.pem"` + ); } + } else { + console.log({ dualCerts, host, wwwDomain, nakedDomain, domain }); + } + if (!isCoolify) { + await forceSSLOnApplication({ domain }); } } catch (error) { console.log(error); diff --git a/src/routes/applications/[id]/index.svelte b/src/routes/applications/[id]/index.svelte index 930088ec5..a5d19eb6b 100644 --- a/src/routes/applications/[id]/index.svelte +++ b/src/routes/applications/[id]/index.svelte @@ -52,6 +52,7 @@ let loading = false; let debug = application.settings.debug; let previews = application.settings.previews; + let dualCerts = application.settings.dualCerts; onMount(() => { domainEl.focus(); @@ -64,8 +65,11 @@ if (name === 'previews') { previews = !previews; } + if (name === 'dualCerts') { + dualCerts = !dualCerts; + } try { - await post(`/applications/${id}/settings.json`, { previews, debug }); + await post(`/applications/${id}/settings.json`, { previews, debug, dualCerts }); return toast.push('Settings saved.'); } catch ({ error }) { return errorNotification(error); @@ -252,7 +256,7 @@
    - +
    - +
    + changeSettings('dualCerts')} + /> +
    {#if !staticDeployments.includes(application.buildPack)}
    @@ -285,6 +297,7 @@
    {/if} + {#if !notNodeDeployments.includes(application.buildPack)}
    @@ -361,8 +374,7 @@
    Features
    -
    - -
      +
      +
      changeSettings('previews')} title="Enable MR/PR Previews" description="Creates previews from pull and merge requests." /> -
    -
      +
    +
    changeSettings('debug')} title="Debug Logs" description="Enable debug logs during build phase.
    (sensitive information could be visible in logs)" /> - +
    diff --git a/src/routes/applications/[id]/settings.json.ts b/src/routes/applications/[id]/settings.json.ts index ddd7bb5ca..6b0b3f808 100644 --- a/src/routes/applications/[id]/settings.json.ts +++ b/src/routes/applications/[id]/settings.json.ts @@ -8,10 +8,10 @@ export const post: RequestHandler = async (event) => { if (status === 401) return { status, body }; const { id } = event.params; - const { debug, previews } = await event.request.json(); + const { debug, previews, dualCerts } = await event.request.json(); try { - await db.setApplicationSettings({ id, debug, previews }); + await db.setApplicationSettings({ id, debug, previews, dualCerts }); return { status: 201 }; } catch (error) { return ErrorHandler(error); diff --git a/src/routes/databases/[id]/_Databases/_CouchDb.svelte b/src/routes/databases/[id]/_Databases/_CouchDb.svelte index 0d41ec184..3cba4ef93 100644 --- a/src/routes/databases/[id]/_Databases/_CouchDb.svelte +++ b/src/routes/databases/[id]/_Databases/_CouchDb.svelte @@ -7,72 +7,62 @@
    CouchDB
    -
    +
    -
    - -
    +
    -
    +
    -
    - -
    +
    -
    +
    -
    - -
    +
    -
    +
    -
    - -
    +
    -
    +
    -
    - -
    +
    diff --git a/src/routes/databases/[id]/_Databases/_Databases.svelte b/src/routes/databases/[id]/_Databases/_Databases.svelte index cd91c8d6a..e09e8d278 100644 --- a/src/routes/databases/[id]/_Databases/_Databases.svelte +++ b/src/routes/databases/[id]/_Databases/_Databases.svelte @@ -88,70 +88,60 @@
    -
    +
    -
    - -
    +
    -
    +
    -
    - {#if database.destinationDockerId} -
    - -
    - {/if} -
    + {#if database.destinationDockerId} +
    + +
    + {/if}
    -
    +
    -
    - -
    +
    -
    +
    -
    - -
    +
    -
    +
    -
    - -
    +
    @@ -166,44 +156,42 @@ {:else if database.type === 'couchdb'} {/if} -
    +
    -
    - -
    +
    Features
    -
    -
      +
      +
      changeSettings('isPublic')} title="Set it public" description="Your database will be reachable over the internet.
      Take security seriously in this case!" /> -
    +
    {#if database.type === 'redis'} -
      +
      changeSettings('appendOnly')} title="Change append only mode" description="Useful if you would like to restore redis data from a backup.
      Database restart is required." /> -
    +
    {/if}
    diff --git a/src/routes/databases/[id]/_Databases/_MongoDB.svelte b/src/routes/databases/[id]/_Databases/_MongoDB.svelte index cbf3ffe35..54518c012 100644 --- a/src/routes/databases/[id]/_Databases/_MongoDB.svelte +++ b/src/routes/databases/[id]/_Databases/_MongoDB.svelte @@ -7,31 +7,27 @@
    MongoDB
    -
    +
    -
    - -
    +
    -
    +
    -
    - -
    +
    diff --git a/src/routes/databases/[id]/_Databases/_MySQL.svelte b/src/routes/databases/[id]/_Databases/_MySQL.svelte index e361cc9fe..4f24862b3 100644 --- a/src/routes/databases/[id]/_Databases/_MySQL.svelte +++ b/src/routes/databases/[id]/_Databases/_MySQL.svelte @@ -7,72 +7,62 @@
    MySQL
    -
    +
    -
    - -
    +
    -
    +
    -
    - -
    +
    -
    +
    -
    - -
    +
    -
    +
    -
    - -
    +
    -
    +
    -
    - -
    +
    diff --git a/src/routes/databases/[id]/_Databases/_PostgreSQL.svelte b/src/routes/databases/[id]/_Databases/_PostgreSQL.svelte index dc585c8e4..758aaccb0 100644 --- a/src/routes/databases/[id]/_Databases/_PostgreSQL.svelte +++ b/src/routes/databases/[id]/_Databases/_PostgreSQL.svelte @@ -7,45 +7,39 @@
    PostgreSQL
    -
    +
    -
    - -
    +
    -
    +
    -
    - -
    +
    -
    +
    -
    - -
    +
    diff --git a/src/routes/databases/[id]/_Databases/_Redis.svelte b/src/routes/databases/[id]/_Databases/_Redis.svelte index ff8f83113..7c02a313e 100644 --- a/src/routes/databases/[id]/_Databases/_Redis.svelte +++ b/src/routes/databases/[id]/_Databases/_Redis.svelte @@ -7,32 +7,17 @@
    Redis
    - -
    +
    -
    - -
    +
    + + +
    +
    {#if containers.length > 0} {#each containers as container} diff --git a/src/routes/applications/[id]/secrets/_Secret.svelte b/src/routes/applications/[id]/secrets/_Secret.svelte index 60c53080b..b5cbd8751 100644 --- a/src/routes/applications/[id]/secrets/_Secret.svelte +++ b/src/routes/applications/[id]/secrets/_Secret.svelte @@ -3,6 +3,11 @@ export let value = ''; export let isBuildSecret = false; export let isNewSecret = false; + export let isPRMRSecret = false; + export let PRMRSecret = {}; + + if (isPRMRSecret) value = PRMRSecret.value; + import { page } from '$app/stores'; import { del, post } from '$lib/api'; import { errorNotification } from '$lib/form'; @@ -36,7 +41,7 @@ } try { - await post(`/applications/${id}/secrets.json`, { name, value, isBuildSecret }); + await post(`/applications/${id}/secrets.json`, { name, value, isBuildSecret, isPRMRSecret }); dispatch('refresh'); if (isNewSecret) { name = ''; @@ -75,9 +80,9 @@ required placeholder="J$#@UIO%HO#$U%H" class="-mx-2 w-64 border-2 border-transparent" - class:bg-transparent={!isNewSecret} - class:cursor-not-allowed={!isNewSecret} - readonly={!isNewSecret} + class:bg-transparent={!isNewSecret && !isPRMRSecret} + class:cursor-not-allowed={!isNewSecret && !isPRMRSecret} + readonly={!isNewSecret && !isPRMRSecret} /> @@ -134,6 +139,10 @@
    + {:else if isPRMRSecret} +
    + +
    {:else}
    diff --git a/src/routes/applications/[id]/secrets/index.json.ts b/src/routes/applications/[id]/secrets/index.json.ts index bed54b950..365a74c87 100644 --- a/src/routes/applications/[id]/secrets/index.json.ts +++ b/src/routes/applications/[id]/secrets/index.json.ts @@ -7,8 +7,9 @@ export const get: RequestHandler = async (event) => { const { teamId, status, body } = await getUserDetails(event); if (status === 401) return { status, body }; + const { id } = event.params; try { - const secrets = await db.listSecrets({ applicationId: event.params.id }); + const secrets = await (await db.listSecrets(id)).filter((secret) => !secret.isPRMRSecret); return { status: 200, body: { @@ -27,16 +28,23 @@ export const post: RequestHandler = async (event) => { if (status === 401) return { status, body }; const { id } = event.params; - const { name, value, isBuildSecret } = await event.request.json(); + const { name, value, isBuildSecret, isPRMRSecret } = await event.request.json(); try { - const found = await db.isSecretExists({ id, name }); - if (found) { - throw { - error: `Secret ${name} already exists.` - }; + if (!isPRMRSecret) { + const found = await db.isSecretExists({ id, name, isPRMRSecret }); + if (found) { + throw { + error: `Secret ${name} already exists.` + }; + } else { + await db.createSecret({ id, name, value, isBuildSecret, isPRMRSecret }); + return { + status: 201 + }; + } } else { - await db.createSecret({ id, name, value, isBuildSecret }); + await db.updateSecret({ id, name, value, isBuildSecret, isPRMRSecret }); return { status: 201 }; From cab7ac7d58140b6fd4c96cedabaa11b437d2ab19 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Sat, 19 Feb 2022 22:37:45 +0100 Subject: [PATCH 32/35] fix: If DNS not found, do not redirect --- src/routes/settings/index.json.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/routes/settings/index.json.ts b/src/routes/settings/index.json.ts index 217b314bd..bd365d5e4 100644 --- a/src/routes/settings/index.json.ts +++ b/src/routes/settings/index.json.ts @@ -1,3 +1,4 @@ +import { dev } from '$app/env'; import { getDomain, getUserDetails } from '$lib/common'; import * as db from '$lib/database'; import { listSettings, ErrorHandler } from '$lib/database'; @@ -43,7 +44,13 @@ export const del: RequestHandler = async (event) => { if (status === 401) return { status, body }; const { fqdn } = await event.request.json(); - const ip = await dns.resolve(event.url.hostname); + let ip; + console.log(fqdn); + try { + ip = await dns.resolve(fqdn); + } catch (error) { + // Do not care. + } try { const domain = getDomain(fqdn); await db.prisma.setting.update({ where: { fqdn }, data: { fqdn: null } }); @@ -53,7 +60,7 @@ export const del: RequestHandler = async (event) => { status: 200, body: { message: 'Domain removed', - redirect: `http://${ip[0]}:3000/settings` + redirect: ip ? `http://${ip[0]}:3000/settings` : undefined } }; } catch (error) { From 7c683668ebfde005555007004160fc3c04d45bd1 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Sun, 20 Feb 2022 00:00:31 +0100 Subject: [PATCH 33/35] feat: Secrets for previews UI: Some CSS changes --- src/lib/buildPacks/docker.ts | 13 +- src/lib/buildPacks/nextjs.ts | 22 +++- src/lib/buildPacks/node.ts | 22 +++- src/lib/buildPacks/nuxtjs.ts | 22 +++- src/lib/buildPacks/static.ts | 22 +++- src/lib/components/CopyPasswordField.svelte | 124 +++++++++--------- src/lib/components/templates.ts | 1 - src/lib/database/secrets.ts | 12 +- src/lib/docker.ts | 15 ++- src/lib/queues/builder.ts | 11 +- src/routes/applications/[id]/index.svelte | 6 +- .../applications/[id]/previews/index.json.ts | 8 +- .../applications/[id]/previews/index.svelte | 21 +-- .../applications/[id]/secrets/_Secret.svelte | 59 +++++---- .../applications/[id]/secrets/index.json.ts | 5 +- .../applications/[id]/secrets/index.svelte | 4 +- .../databases/[id]/_Databases/_CouchDb.svelte | 2 +- .../databases/[id]/_Databases/_MongoDB.svelte | 2 +- .../databases/[id]/_Databases/_MySQL.svelte | 2 +- .../[id]/_Databases/_PostgreSQL.svelte | 2 +- .../databases/[id]/_Databases/_Redis.svelte | 2 +- .../services/[id]/_Services/_MinIO.svelte | 6 +- src/routes/settings/index.svelte | 2 +- src/tailwind.css | 4 +- 24 files changed, 243 insertions(+), 146 deletions(-) diff --git a/src/lib/buildPacks/docker.ts b/src/lib/buildPacks/docker.ts index 5bc6ce453..af000e551 100644 --- a/src/lib/buildPacks/docker.ts +++ b/src/lib/buildPacks/docker.ts @@ -9,7 +9,8 @@ export default async function ({ docker, buildId, baseDirectory, - secrets + secrets, + pullmergeRequestId }) { try { let file = `${workdir}/Dockerfile`; @@ -24,7 +25,15 @@ export default async function ({ if (secrets.length > 0) { secrets.forEach((secret) => { if (secret.isBuildSecret) { - Dockerfile.push(`ARG ${secret.name} ${secret.value}`); + if (pullmergeRequestId) { + if (secret.isPRMRSecret) { + Dockerfile.push(`ARG ${secret.name} ${secret.value}`); + } + } else { + if (!secret.isPRMRSecret) { + Dockerfile.push(`ARG ${secret.name} ${secret.value}`); + } + } } }); } diff --git a/src/lib/buildPacks/nextjs.ts b/src/lib/buildPacks/nextjs.ts index 53a7f884e..648208d83 100644 --- a/src/lib/buildPacks/nextjs.ts +++ b/src/lib/buildPacks/nextjs.ts @@ -2,8 +2,16 @@ import { buildImage } from '$lib/docker'; import { promises as fs } from 'fs'; const createDockerfile = async (data, image): Promise => { - const { workdir, port, installCommand, buildCommand, startCommand, baseDirectory, secrets } = - data; + const { + workdir, + port, + installCommand, + buildCommand, + startCommand, + baseDirectory, + secrets, + pullmergeRequestId + } = data; const Dockerfile: Array = []; Dockerfile.push(`FROM ${image}`); @@ -11,7 +19,15 @@ const createDockerfile = async (data, image): Promise => { if (secrets.length > 0) { secrets.forEach((secret) => { if (secret.isBuildSecret) { - Dockerfile.push(`ARG ${secret.name} ${secret.value}`); + if (pullmergeRequestId) { + if (secret.isPRMRSecret) { + Dockerfile.push(`ARG ${secret.name} ${secret.value}`); + } + } else { + if (!secret.isPRMRSecret) { + Dockerfile.push(`ARG ${secret.name} ${secret.value}`); + } + } } }); } diff --git a/src/lib/buildPacks/node.ts b/src/lib/buildPacks/node.ts index 53a7f884e..648208d83 100644 --- a/src/lib/buildPacks/node.ts +++ b/src/lib/buildPacks/node.ts @@ -2,8 +2,16 @@ import { buildImage } from '$lib/docker'; import { promises as fs } from 'fs'; const createDockerfile = async (data, image): Promise => { - const { workdir, port, installCommand, buildCommand, startCommand, baseDirectory, secrets } = - data; + const { + workdir, + port, + installCommand, + buildCommand, + startCommand, + baseDirectory, + secrets, + pullmergeRequestId + } = data; const Dockerfile: Array = []; Dockerfile.push(`FROM ${image}`); @@ -11,7 +19,15 @@ const createDockerfile = async (data, image): Promise => { if (secrets.length > 0) { secrets.forEach((secret) => { if (secret.isBuildSecret) { - Dockerfile.push(`ARG ${secret.name} ${secret.value}`); + if (pullmergeRequestId) { + if (secret.isPRMRSecret) { + Dockerfile.push(`ARG ${secret.name} ${secret.value}`); + } + } else { + if (!secret.isPRMRSecret) { + Dockerfile.push(`ARG ${secret.name} ${secret.value}`); + } + } } }); } diff --git a/src/lib/buildPacks/nuxtjs.ts b/src/lib/buildPacks/nuxtjs.ts index 53a7f884e..648208d83 100644 --- a/src/lib/buildPacks/nuxtjs.ts +++ b/src/lib/buildPacks/nuxtjs.ts @@ -2,8 +2,16 @@ import { buildImage } from '$lib/docker'; import { promises as fs } from 'fs'; const createDockerfile = async (data, image): Promise => { - const { workdir, port, installCommand, buildCommand, startCommand, baseDirectory, secrets } = - data; + const { + workdir, + port, + installCommand, + buildCommand, + startCommand, + baseDirectory, + secrets, + pullmergeRequestId + } = data; const Dockerfile: Array = []; Dockerfile.push(`FROM ${image}`); @@ -11,7 +19,15 @@ const createDockerfile = async (data, image): Promise => { if (secrets.length > 0) { secrets.forEach((secret) => { if (secret.isBuildSecret) { - Dockerfile.push(`ARG ${secret.name} ${secret.value}`); + if (pullmergeRequestId) { + if (secret.isPRMRSecret) { + Dockerfile.push(`ARG ${secret.name} ${secret.value}`); + } + } else { + if (!secret.isPRMRSecret) { + Dockerfile.push(`ARG ${secret.name} ${secret.value}`); + } + } } }); } diff --git a/src/lib/buildPacks/static.ts b/src/lib/buildPacks/static.ts index 0db1a0c83..d71eea6e1 100644 --- a/src/lib/buildPacks/static.ts +++ b/src/lib/buildPacks/static.ts @@ -2,8 +2,16 @@ import { buildCacheImageWithNode, buildImage } from '$lib/docker'; import { promises as fs } from 'fs'; const createDockerfile = async (data, image): Promise => { - const { applicationId, tag, workdir, buildCommand, baseDirectory, publishDirectory, secrets } = - data; + const { + applicationId, + tag, + workdir, + buildCommand, + baseDirectory, + publishDirectory, + secrets, + pullmergeRequestId + } = data; const Dockerfile: Array = []; Dockerfile.push(`FROM ${image}`); @@ -11,7 +19,15 @@ const createDockerfile = async (data, image): Promise => { if (secrets.length > 0) { secrets.forEach((secret) => { if (secret.isBuildSecret) { - Dockerfile.push(`ARG ${secret.name} ${secret.value}`); + if (pullmergeRequestId) { + if (secret.isPRMRSecret) { + Dockerfile.push(`ARG ${secret.name} ${secret.value}`); + } + } else { + if (!secret.isPRMRSecret) { + Dockerfile.push(`ARG ${secret.name} ${secret.value}`); + } + } } }); } diff --git a/src/lib/components/CopyPasswordField.svelte b/src/lib/components/CopyPasswordField.svelte index ac2ba94d4..648fc3278 100644 --- a/src/lib/components/CopyPasswordField.svelte +++ b/src/lib/components/CopyPasswordField.svelte @@ -1,9 +1,9 @@ -
    showActions(true)} - on:mouseleave={() => showActions(false)} -> +
    {#if !isPasswordField || showPassword} {#if textarea}