diff --git a/package.json b/package.json index e03c678b0..b3945abee 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.16", "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", @@ -25,9 +25,9 @@ "prepare": "husky install" }, "devDependencies": { - "@sveltejs/adapter-node": "1.0.0-next.67", - "@sveltejs/adapter-static": "1.0.0-next.27", - "@sveltejs/kit": "1.0.0-next.259", + "@sveltejs/adapter-node": "1.0.0-next.68", + "@sveltejs/adapter-static": "1.0.0-next.28", + "@sveltejs/kit": "1.0.0-next.278", "@types/bcrypt": "5.0.0", "@types/js-cookie": "3.0.1", "@types/node": "17.0.18", @@ -50,7 +50,7 @@ "svelte": "3.46.4", "svelte-check": "2.4.3", "svelte-preprocess": "4.10.3", - "tailwindcss": "3.0.22", + "tailwindcss": "3.0.23", "ts-node": "10.5.0", "tslib": "2.3.1", "typescript": "4.5.5" @@ -59,9 +59,9 @@ "dependencies": { "@iarna/toml": "2.2.5", "@prisma/client": "3.9.2", - "@sentry/node": "6.17.8", + "@sentry/node": "6.17.9", "bcrypt": "5.0.1", - "bullmq": "1.72.0", + "bullmq": "1.73.0", "compare-versions": "4.1.3", "cookie": "0.4.2", "cuid": "2.1.8", @@ -69,14 +69,15 @@ "dockerode": "3.3.1", "dotenv-extended": "2.9.0", "generate-password": "1.7.0", - "get-port": "6.0.0", + "get-port": "6.1.0", "got": "12.0.1", "js-cookie": "3.0.1", "js-yaml": "4.1.0", "jsonwebtoken": "8.5.1", "node-forge": "1.2.1", - "svelte-kit-cookie-session": "2.0.2", - "unique-names-generator": "4.6.0" + "svelte-kit-cookie-session": "2.1.2", + "tailwindcss-scrollbar": "^0.1.0", + "unique-names-generator": "4.7.1" }, "prisma": { "seed": "node prisma/seed.cjs" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 58ddfd8c6..4b0d07310 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3,10 +3,10 @@ lockfileVersion: 5.3 specifiers: '@iarna/toml': 2.2.5 '@prisma/client': 3.9.2 - '@sentry/node': 6.17.8 - '@sveltejs/adapter-node': 1.0.0-next.67 - '@sveltejs/adapter-static': 1.0.0-next.27 - '@sveltejs/kit': 1.0.0-next.259 + '@sentry/node': 6.17.9 + '@sveltejs/adapter-node': 1.0.0-next.68 + '@sveltejs/adapter-static': 1.0.0-next.28 + '@sveltejs/kit': 1.0.0-next.278 '@types/bcrypt': 5.0.0 '@types/js-cookie': 3.0.1 '@types/node': 17.0.18 @@ -16,7 +16,7 @@ specifiers: '@zerodevx/svelte-toast': 0.6.3 autoprefixer: 10.4.2 bcrypt: 5.0.1 - bullmq: 1.72.0 + bullmq: 1.73.0 compare-versions: 4.1.3 cookie: 0.4.2 cross-var: 1.1.0 @@ -28,7 +28,7 @@ specifiers: eslint-config-prettier: 8.3.0 eslint-plugin-svelte3: 3.2.1 generate-password: 1.7.0 - get-port: 6.0.0 + get-port: 6.1.0 got: 12.0.1 husky: 7.0.4 js-cookie: 3.0.1 @@ -43,20 +43,21 @@ 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.1.2 svelte-preprocess: 4.10.3 - tailwindcss: 3.0.22 + tailwindcss: 3.0.23 + tailwindcss-scrollbar: ^0.1.0 ts-node: 10.5.0 tslib: 2.3.1 typescript: 4.5.5 - unique-names-generator: 4.6.0 + unique-names-generator: 4.7.1 dependencies: '@iarna/toml': 2.2.5 '@prisma/client': 3.9.2_prisma@3.9.2 - '@sentry/node': 6.17.8 + '@sentry/node': 6.17.9 bcrypt: 5.0.1 - bullmq: 1.72.0 + bullmq: 1.73.0 compare-versions: 4.1.3 cookie: 0.4.2 cuid: 2.1.8 @@ -64,19 +65,20 @@ dependencies: dockerode: 3.3.1 dotenv-extended: 2.9.0 generate-password: 1.7.0 - get-port: 6.0.0 + get-port: 6.1.0 got: 12.0.1 js-cookie: 3.0.1 js-yaml: 4.1.0 jsonwebtoken: 8.5.1 node-forge: 1.2.1 - svelte-kit-cookie-session: 2.0.5 - unique-names-generator: 4.6.0 + svelte-kit-cookie-session: 2.1.2 + tailwindcss-scrollbar: 0.1.0_tailwindcss@3.0.23 + unique-names-generator: 4.7.1 devDependencies: - '@sveltejs/adapter-node': 1.0.0-next.67 - '@sveltejs/adapter-static': 1.0.0-next.27 - '@sveltejs/kit': 1.0.0-next.259_svelte@3.46.4 + '@sveltejs/adapter-node': 1.0.0-next.68 + '@sveltejs/adapter-static': 1.0.0-next.28 + '@sveltejs/kit': 1.0.0-next.278_svelte@3.46.4 '@types/bcrypt': 5.0.0 '@types/js-cookie': 3.0.1 '@types/node': 17.0.18 @@ -99,7 +101,7 @@ devDependencies: svelte: 3.46.4 svelte-check: 2.4.3_postcss@8.4.6+svelte@3.46.4 svelte-preprocess: 4.10.3_88b359da5cac6d8f6ee1bbb7080a3fa9 - tailwindcss: 3.0.22_c940fbabf228b85b1c73d314b43e31f1 + tailwindcss: 3.0.23_c940fbabf228b85b1c73d314b43e31f1 ts-node: 10.5.0_f3bd4037939c2ed2942ba074291f8ef2 tslib: 2.3.1 typescript: 4.5.5 @@ -293,56 +295,56 @@ packages: picomatch: 2.3.0 dev: true - /@sentry/core/6.17.8: + /@sentry/core/6.17.9: resolution: { - integrity: sha512-4WTjgQom75Rvgn6XYy6e7vMIbWlj8utau1wWvr7kjqFKuuuuycRvPgVzAdVr4B3WDHHCInAZpUchsOLs2qwIEA== + integrity: sha512-14KalmTholGUtgdh9TklO+jUpyQ/D3OGkhlH1rnGQGoJgFy2eYm+s+MnUEMxFdGIUCz5kOteuNqYZxaDmFagpQ== } engines: { node: '>=6' } dependencies: - '@sentry/hub': 6.17.8 - '@sentry/minimal': 6.17.8 - '@sentry/types': 6.17.8 - '@sentry/utils': 6.17.8 + '@sentry/hub': 6.17.9 + '@sentry/minimal': 6.17.9 + '@sentry/types': 6.17.9 + '@sentry/utils': 6.17.9 tslib: 1.14.1 dev: false - /@sentry/hub/6.17.8: + /@sentry/hub/6.17.9: resolution: { - integrity: sha512-GW0XYpkoQu/kSJaTLfsF4extHDOBPNRnT0qKr/YO20Z5wGxYp8LsdnAuU3njcFHcAV2F/QDTj2BPq1U385/4+A== + integrity: sha512-34EdrweWDbBV9EzEFIXcO+JeoyQmKzQVJxpTKZoJA6PUwf2NrndaUdjlkDEtBEzjuLUTxhLxtOzEsYs1O6RVcg== } engines: { node: '>=6' } dependencies: - '@sentry/types': 6.17.8 - '@sentry/utils': 6.17.8 + '@sentry/types': 6.17.9 + '@sentry/utils': 6.17.9 tslib: 1.14.1 dev: false - /@sentry/minimal/6.17.8: + /@sentry/minimal/6.17.9: resolution: { - integrity: sha512-VJXFZBO/O8SViK0fdzodxpNr+pbpgczNgLpz/MNuSooV6EBesgCMVjXtxDUp1Ie1odc0GUprN/ZMLYBmYdIrKQ== + integrity: sha512-T3PMCHcKk6lkZq6zKgANrYJJxXBXKOe+ousV1Fas1rVBMv7dtKfsa4itqQHszcW9shusPDiaQKIJ4zRLE5LKmg== } engines: { node: '>=6' } dependencies: - '@sentry/hub': 6.17.8 - '@sentry/types': 6.17.8 + '@sentry/hub': 6.17.9 + '@sentry/types': 6.17.9 tslib: 1.14.1 dev: false - /@sentry/node/6.17.8: + /@sentry/node/6.17.9: resolution: { - integrity: sha512-b3zg1XjKtxp7o821ENORO1CCzMM4QzKP01rzztMwyMcj28dmUq36QXoQAnwdKn7jEYkJdLnMeniIBR6U6NUJrQ== + integrity: sha512-jbn+q7qPGOh6D7nYoYGaAlmuvMDpQmyMwBtUVYybuZp2AALe43O3Z4LtoJ+1+F31XowpsIPZx1mwNs4ZrILskA== } engines: { node: '>=6' } dependencies: - '@sentry/core': 6.17.8 - '@sentry/hub': 6.17.8 - '@sentry/tracing': 6.17.8 - '@sentry/types': 6.17.8 - '@sentry/utils': 6.17.8 + '@sentry/core': 6.17.9 + '@sentry/hub': 6.17.9 + '@sentry/tracing': 6.17.9 + '@sentry/types': 6.17.9 + '@sentry/utils': 6.17.9 cookie: 0.4.2 https-proxy-agent: 5.0.0 lru_map: 0.3.3 @@ -351,36 +353,36 @@ packages: - supports-color dev: false - /@sentry/tracing/6.17.8: + /@sentry/tracing/6.17.9: resolution: { - integrity: sha512-WJ3W8O6iPI3w7MrzTnYcw3s5PGBNFqT4b9oBCl5Ndjexs8DsGlQOxjrsipo36z6TpnRHpAE4FEbOETb2R8JRJQ== + integrity: sha512-5Rb/OS4ryNJLvz2nv6wyjwhifjy6veqaF9ffLrwFYij/WDy7m62ASBblxgeiI3fbPLX0aBRFWIJAq1vko26+AQ== } engines: { node: '>=6' } dependencies: - '@sentry/hub': 6.17.8 - '@sentry/minimal': 6.17.8 - '@sentry/types': 6.17.8 - '@sentry/utils': 6.17.8 + '@sentry/hub': 6.17.9 + '@sentry/minimal': 6.17.9 + '@sentry/types': 6.17.9 + '@sentry/utils': 6.17.9 tslib: 1.14.1 dev: false - /@sentry/types/6.17.8: + /@sentry/types/6.17.9: resolution: { - integrity: sha512-0i0f+dpvV62Pm5QMVBHNfEsTGIXoXRGQbeN2LGL4XbhzrzUmIrBPzrnZHv9c/JYtSJnI6A0B9OG7Bdlh3aku+Q== + integrity: sha512-xuulX6qUCL14ayEOh/h6FUIvZtsi1Bx34dSOaWDrjXUOJHJAM7214uiqW1GZxPJ13YuaUIubjTSfDmSQ9CBzTw== } engines: { node: '>=6' } dev: false - /@sentry/utils/6.17.8: + /@sentry/utils/6.17.9: resolution: { - integrity: sha512-cAOM53A5FHv95hpDuXKJU8rI4B1XdZ6qe3Yo+/nDS9QDpOgzvyjcItgXPvKW1wUjdHCcnwu7VBfBxB7teYOW9g== + integrity: sha512-4eo9Z3JlJCGlGrQRbtZWL+L9NnlUXgTbfK3Lk7oO8D1ev8R5b5+iE6tZHTvU5rQRcq6zu+POT+tK5u9oxc/rnQ== } engines: { node: '>=6' } dependencies: - '@sentry/types': 6.17.8 + '@sentry/types': 6.17.9 tslib: 1.14.1 dev: false @@ -392,28 +394,28 @@ packages: engines: { node: '>=10' } dev: false - /@sveltejs/adapter-node/1.0.0-next.67: + /@sveltejs/adapter-node/1.0.0-next.68: resolution: { - integrity: sha512-+LuLn91xARZsRANiQNIIDpMMncUTnP2pJc8tyL+FdpVvs5UtlvkYJpeCBPFqjjseRpIIbi8Slu89GCdrRXBDUg== + integrity: sha512-MiEjtl15Aupm6bjirVlq0kkc9AL8qDXz/blsh4jYMsaiidmcEHeDgfZQFM5YiXy95DbxV30MAkhwCQiYK/J8Kw== } dependencies: tiny-glob: 0.2.9 dev: true - /@sveltejs/adapter-static/1.0.0-next.27: + /@sveltejs/adapter-static/1.0.0-next.28: resolution: { - integrity: sha512-dcN1p1D7ZY/a9SClfN14mgm9pyWbLxdwM9gzPMZG6xXOoqMtwI03aZOFgGGumHPdv+XcGRZM96vUSRoDm6vBJQ== + integrity: sha512-c4xLyeSwnbGQxe4f1SLpHTbxZDm3TEr43scR3tOlVgQN+mnAL9aDdl3nTtdzWmrUDmDEmY4GriAwLyFLZuINLw== } dependencies: tiny-glob: 0.2.9 dev: true - /@sveltejs/kit/1.0.0-next.259_svelte@3.46.4: + /@sveltejs/kit/1.0.0-next.278_svelte@3.46.4: resolution: { - integrity: sha512-+Tss6cQXmpi4Jno/ZP0zJ3INBLMED+WeW4UI81tmexheC76Y2p+cbInneKO/REx/8QFo1iroYrWAUkZPsOg8Ew== + integrity: sha512-WT93Wnu05X9WG9BMMk/dj0gy6R7iXm9aXRDVgmIl9z8jT2ukejgmkhi5IwBYrK0OMIUALRVfukn+iy+srPc91Q== } engines: { node: '>=14.13' } hasBin: true @@ -1746,10 +1748,10 @@ packages: ieee754: 1.2.1 dev: false - /bullmq/1.72.0: + /bullmq/1.73.0: resolution: { - integrity: sha512-Q0pk6GphHyYsacpjZZFhjp/+TY+2g2FDsJS3qwIyskQL4j7vZaa1iYX3gKDEBn4C5eZMP1EOl9GWkm2bhdB0Wg== + integrity: sha512-+BF7yeGagYD/iMkM3FA8Wvb3j3MyKE/OdXv404+nQjUsKXfL7PbqX5NSA9lBtFzOdyFx9ZWyKRnBwuGQsLfM0w== } dependencies: cron-parser: 2.18.0 @@ -3114,10 +3116,10 @@ packages: engines: { node: '>=8' } dev: false - /get-port/6.0.0: + /get-port/6.1.0: resolution: { - integrity: sha512-qSVkVF6Eq1GdL/cBNiFuP4nUHMF7OEMTqEjC6alR2N90u8BFOoO0PFhNTX2QtAUoGrz8NnrSWj85TZ8YXZ6LOA== + integrity: sha512-JKnPFW/G2ZRirH/25sLK1aLBQktJfQLixzMMuMBP8A2G/ivSaIwdTnlJeO7PWeyhyIGVorezNf6+CXZU9i0cIQ== } engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } dev: false @@ -5203,10 +5205,10 @@ packages: svelte: 3.46.4 dev: true - /svelte-kit-cookie-session/2.0.5: + /svelte-kit-cookie-session/2.1.2: resolution: { - integrity: sha512-IX1IXtn42UTz/isem1LqH0SAZdCx6Z6Iu2V4Q83V2EScFbXZWfeFY08Azl8ZrPKdIDhSNHBLAAumRjA6TBxCvQ== + integrity: sha512-PfxIWDhiyYWu7iKlL0GHpmwDrdFh+rX/WmBzOuvctF25UqngIo9MCiegWBSBLE1RBwNs5UqaIeI8+vligmY07g== } dev: false @@ -5288,10 +5290,21 @@ packages: strip-ansi: 6.0.1 dev: true - /tailwindcss/3.0.22_c940fbabf228b85b1c73d314b43e31f1: + /tailwindcss-scrollbar/0.1.0_tailwindcss@3.0.23: resolution: { - integrity: sha512-F8lt74RlNZirnkaSk310+vGQta7c0/hgx7/bqxruM4wS9lp8oqV93lzavajC3VT0Lp4UUtUVIt8ifKcmGzkr0A== + integrity: sha512-egipxw4ooQDh94x02XQpPck0P0sfwazwoUGfA9SedPATIuYDR+6qe8d31Gl7YsSMRiOKDkkqfI0kBvEw9lT/Hg== + } + peerDependencies: + tailwindcss: '>= 2.x.x' + dependencies: + tailwindcss: 3.0.23_c940fbabf228b85b1c73d314b43e31f1 + dev: false + + /tailwindcss/3.0.23_c940fbabf228b85b1c73d314b43e31f1: + resolution: + { + integrity: sha512-+OZOV9ubyQ6oI2BXEhzw4HrqvgcARY38xv3zKcjnWtMIZstEsXdI9xftd1iB7+RbOnj2HOEzkA0OyB5BaSxPQA== } engines: { node: '>=12.13.0' } hasBin: true @@ -5515,10 +5528,10 @@ packages: function.name: 1.0.13 dev: false - /unique-names-generator/4.6.0: + /unique-names-generator/4.7.1: resolution: { - integrity: sha512-m0fke1emBeT96UYn2psPQYwljooDWRTKt9oUZ5vlt88ZFMBGxqwPyLHXwCfkbgdm8jzioCp7oIpo6KdM+fnUlQ== + integrity: sha512-lMx9dX+KRmG8sq6gulYYpKWZc9RlGsgBR6aoO8Qsm3qvkSJ+3rAymr+TnV8EDMrIrwuFJ4kruzMWM/OpYzPoow== } engines: { node: '>=8' } dev: false 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/migrations/20220219231255_prmr_secrets/migration.sql b/prisma/migrations/20220219231255_prmr_secrets/migration.sql new file mode 100644 index 000000000..728fcae36 --- /dev/null +++ b/prisma/migrations/20220219231255_prmr_secrets/migration.sql @@ -0,0 +1,19 @@ +-- RedefineTables +PRAGMA foreign_keys=OFF; +CREATE TABLE "new_Secret" ( + "id" TEXT NOT NULL PRIMARY KEY, + "name" TEXT NOT NULL, + "value" TEXT NOT NULL, + "isPRMRSecret" BOOLEAN NOT NULL DEFAULT false, + "isBuildSecret" BOOLEAN NOT NULL DEFAULT false, + "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" DATETIME NOT NULL, + "applicationId" TEXT NOT NULL, + CONSTRAINT "Secret_applicationId_fkey" FOREIGN KEY ("applicationId") REFERENCES "Application" ("id") ON DELETE RESTRICT ON UPDATE CASCADE +); +INSERT INTO "new_Secret" ("applicationId", "createdAt", "id", "isBuildSecret", "name", "updatedAt", "value") SELECT "applicationId", "createdAt", "id", "isBuildSecret", "name", "updatedAt", "value" FROM "Secret"; +DROP TABLE "Secret"; +ALTER TABLE "new_Secret" RENAME TO "Secret"; +CREATE UNIQUE INDEX "Secret_name_applicationId_isPRMRSecret_key" ON "Secret"("name", "applicationId", "isPRMRSecret"); +PRAGMA foreign_key_check; +PRAGMA foreign_keys=ON; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index b064d09ab..7599602fb 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,15 +107,16 @@ model ApplicationSettings { model Secret { id String @id @default(cuid()) - name String + name String value String + isPRMRSecret Boolean @default(false) isBuildSecret Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt application Application @relation(fields: [applicationId], references: [id]) applicationId String - @@unique([name, applicationId]) + @@unique([name, applicationId, isPRMRSecret]) } model BuildLog { @@ -234,6 +237,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/global.d.ts b/src/app.d.ts similarity index 50% rename from src/global.d.ts rename to src/app.d.ts index 4a2702fbc..c3921e0f2 100644 --- a/src/global.d.ts +++ b/src/app.d.ts @@ -1,74 +1,26 @@ /// -interface Cookies { - teamId?: string; - gitlabToken?: string; - 'kit.session'?: string; -} -interface Locals { - gitlabToken?: string; - user: { - teamId: string; - permission: string; - isAdmin: boolean; - }; - session: { - data: { - uid?: string; - teams?: string[]; - expires?: string; - }; - }; + +declare namespace App { + interface Locals { + session: import('svelte-kit-cookie-session').Session; + cookies: Record; + } + interface Platform {} + interface Session extends SessionData {} + interface Stuff {} } -type Applications = { - name: string; - domain: string; -}; - -interface Hash { - iv: string; - content: string; +interface SessionData { + version?: string; + userId?: string | null; + teamId?: string | null; + permission?: string; + isAdmin?: boolean; + expires?: string | null; + gitlabToken?: string | null; + ghToken?: string | null; } -interface BuildPack { - name: string; -} - -// TODO: Not used, not working what?! -enum GitSource { - Github = 'github', - Gitlab = 'gitlab', - Bitbucket = 'bitbucket' -} - -type RawHaproxyConfiguration = { - _version: number; - data: string; -}; - -type NewTransaction = { - _version: number; - id: string; - status: string; -}; - -type HttpRequestRuleForceSSL = { - return_hdrs: null; - cond: string; - cond_test: string; - index: number; - redir_code: number; - redir_type: string; - redir_value: string; - type: string; -}; - -// TODO: No any please -type HttpRequestRule = { - _version: number; - data: Array; -}; - type DateTimeFormatOptions = { localeMatcher?: 'lookup' | 'best fit'; weekday?: 'long' | 'short' | 'narrow'; @@ -84,3 +36,24 @@ type DateTimeFormatOptions = { hour12?: boolean; timeZone?: string; }; + +interface Hash { + iv: string; + content: string; +} + +type RawHaproxyConfiguration = { + _version: number; + data: string; +}; + +type NewTransaction = { + _version: number; + id: string; + status: string; +}; + +type Application = { + name: string; + domain: string; +}; diff --git a/src/hooks.ts b/src/hooks.ts index d4fea1baf..bdd1f9234 100644 --- a/src/hooks.ts +++ b/src/hooks.ts @@ -2,7 +2,7 @@ import dotEnvExtended from 'dotenv-extended'; dotEnvExtended.load(); import type { GetSession } from '@sveltejs/kit'; import { handleSession } from 'svelte-kit-cookie-session'; -import { getUserDetails, isTeamIdTokenAvailable, sentry } from '$lib/common'; +import { getUserDetails, sentry } from '$lib/common'; import { version } from '$lib/common'; import cookie from 'cookie'; import { dev } from '$app/env'; @@ -10,27 +10,38 @@ 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; try { - const cookies: Cookies = cookie.parse(event.request.headers.get('cookie') || ''); - if (cookies['kit.session']) { - const { permission, teamId } = await getUserDetails(event, false); - event.locals.user = { - teamId, - permission, - isAdmin: permission === 'admin' || permission === 'owner' - }; - } - if (cookies.gitlabToken) { - event.locals.gitlabToken = cookies.gitlabToken; + if (event.locals.cookies) { + let gitlabToken = event.locals.cookies.gitlabToken || null; + let ghToken = event.locals.cookies.ghToken || null; + if (event.locals.cookies['kit.session']) { + const { permission, teamId, userId } = await getUserDetails(event, false); + const newSession = { + userId, + teamId, + permission, + isAdmin: permission === 'admin' || permission === 'owner', + expires: event.locals.session.data.expires, + gitlabToken, + ghToken + }; + + if (JSON.stringify(event.locals.session.data) !== JSON.stringify(newSession)) { + event.locals.session.data = { ...newSession }; + } + } } + response = await resolve(event, { ssr: !event.url.pathname.startsWith('/webhooks/success') }); } catch (error) { + console.log(error); response = await resolve(event, { ssr: !event.url.pathname.startsWith('/webhooks/success') }); @@ -61,17 +72,13 @@ export const handle = handleSession( } ); -export const getSession: GetSession = function (request) { +export const getSession: GetSession = function ({ locals }) { return { version, - gitlabToken: request.locals?.gitlabToken || null, - uid: request.locals.session.data?.uid || null, - teamId: request.locals.user?.teamId || null, - permission: request.locals.user?.permission, - isAdmin: request.locals.user?.isAdmin || false + ...locals.session.data }; }; export async function handleError({ error, event }) { - if (!dev) sentry.captureException(error, { event }); + if (!dev) sentry.captureException(error, event); } 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/common.ts b/src/lib/common.ts index 3740ba231..3ec0c923c 100644 --- a/src/lib/common.ts +++ b/src/lib/common.ts @@ -67,7 +67,7 @@ export const isTeamIdTokenAvailable = (request) => { }; export const getTeam = (event) => { - const cookies: Cookies = Cookie.parse(event.request.headers.get('cookie')); + const cookies = Cookie.parse(event.request.headers.get('cookie')); if (cookies.teamId) { return cookies.teamId; } else if (event.locals.session.data.teamId) { @@ -78,7 +78,7 @@ export const getTeam = (event) => { export const getUserDetails = async (event, isAdminRequired = true) => { const teamId = getTeam(event); - const userId = event.locals.session.data.uid || null; + const userId = event.locals.session.data.userId || null; const { permission = 'read' } = await db.prisma.permission.findFirst({ where: { teamId, userId }, select: { permission: true }, diff --git a/src/lib/components/CopyPasswordField.svelte b/src/lib/components/CopyPasswordField.svelte index ab43f48bd..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} -
+ : null}>{service.wordpress.extraConfig || 'N/A'}
MySQL
-
+
-
- -
+
-
+
-
- -
+
-
+
-
- -
+
-
+
-
- -
+
-
+
-
- -
+
diff --git a/src/routes/services/[id]/check.json.ts b/src/routes/services/[id]/check.json.ts index 5fb1915a0..861daee84 100644 --- a/src/routes/services/[id]/check.json.ts +++ b/src/routes/services/[id]/check.json.ts @@ -17,7 +17,7 @@ export const post: RequestHandler = async (event) => { return { status: found ? 500 : 200, body: { - error: found && `Domain ${getDomain(fqdn)} is already configured` + error: found && `Domain ${getDomain(fqdn).replace('www.', '')} is already configured` } }; } catch (error) { diff --git a/src/routes/services/[id]/configuration/version.json.ts b/src/routes/services/[id]/configuration/version.json.ts index 57d86fed2..f1a1a9522 100644 --- a/src/routes/services/[id]/configuration/version.json.ts +++ b/src/routes/services/[id]/configuration/version.json.ts @@ -30,7 +30,7 @@ export const post: RequestHandler = async (event) => { const { version } = await event.request.json(); try { - await db.setService({ id, version }); + await db.setServiceVersion({ id, version }); return { status: 201 }; diff --git a/src/routes/services/[id]/minio/stop.json.ts b/src/routes/services/[id]/minio/stop.json.ts index 95f227009..aed702b1b 100644 --- a/src/routes/services/[id]/minio/stop.json.ts +++ b/src/routes/services/[id]/minio/stop.json.ts @@ -35,7 +35,7 @@ export const post: RequestHandler = async (event) => { } try { await stopTcpHttpProxy(destinationDocker, publicPort); - await configureSimpleServiceProxyOff({ domain }); + await configureSimpleServiceProxyOff(fqdn); } catch (error) { console.log(error); } diff --git a/src/routes/services/[id]/nocodb/stop.json.ts b/src/routes/services/[id]/nocodb/stop.json.ts index ad48b5dce..f15ba1012 100644 --- a/src/routes/services/[id]/nocodb/stop.json.ts +++ b/src/routes/services/[id]/nocodb/stop.json.ts @@ -28,7 +28,7 @@ export const post: RequestHandler = async (event) => { console.error(error); } try { - await configureSimpleServiceProxyOff({ domain }); + await configureSimpleServiceProxyOff(fqdn); } catch (error) { console.log(error); } diff --git a/src/routes/services/[id]/plausibleanalytics/start.json.ts b/src/routes/services/[id]/plausibleanalytics/start.json.ts index 274c59bd9..94c2e46f1 100644 --- a/src/routes/services/[id]/plausibleanalytics/start.json.ts +++ b/src/routes/services/[id]/plausibleanalytics/start.json.ts @@ -60,7 +60,7 @@ export const post: RequestHandler = async (event) => { } }, postgresql: { - volume: `${plausibleDbId}-postgresql-data:/var/lib/postgresql/data`, + volume: `${plausibleDbId}-postgresql-data:/bitnami/postgresql/`, image: 'bitnami/postgresql:13.2.0', environmentVariables: { POSTGRESQL_PASSWORD: postgresqlPassword, @@ -136,7 +136,6 @@ COPY ./init-db.sh /docker-entrypoint-initdb.d/init-db.sh`; 'sh -c "sleep 10 && /entrypoint.sh db createdb && /entrypoint.sh db migrate && /entrypoint.sh db init-admin && /entrypoint.sh run"', networks: [network], environment: config.plausibleAnalytics.environmentVariables, - volumes: [config.postgresql.volume], restart: 'always', depends_on: [`${id}-postgresql`, `${id}-clickhouse`], labels: makeLabelForServices('plausibleAnalytics') diff --git a/src/routes/services/[id]/plausibleanalytics/stop.json.ts b/src/routes/services/[id]/plausibleanalytics/stop.json.ts index c6e59277d..d9b42d7b3 100644 --- a/src/routes/services/[id]/plausibleanalytics/stop.json.ts +++ b/src/routes/services/[id]/plausibleanalytics/stop.json.ts @@ -38,7 +38,7 @@ export const post: RequestHandler = async (event) => { } try { - await configureSimpleServiceProxyOff({ domain }); + await configureSimpleServiceProxyOff(fqdn); } catch (error) { console.log(error); } diff --git a/src/routes/services/[id]/settings.json.ts b/src/routes/services/[id]/settings.json.ts new file mode 100644 index 000000000..50488cf93 --- /dev/null +++ b/src/routes/services/[id]/settings.json.ts @@ -0,0 +1,19 @@ +import { getUserDetails } from '$lib/common'; +import * as db from '$lib/database'; +import { ErrorHandler } from '$lib/database'; +import type { RequestHandler } from '@sveltejs/kit'; + +export const post: RequestHandler = async (event) => { + const { teamId, status, body } = await getUserDetails(event); + if (status === 401) return { status, body }; + + const { id } = event.params; + const { dualCerts } = await event.request.json(); + + try { + await db.setServiceSettings({ id, dualCerts }); + return { status: 201 }; + } catch (error) { + return ErrorHandler(error); + } +}; diff --git a/src/routes/services/[id]/vaultwarden/stop.json.ts b/src/routes/services/[id]/vaultwarden/stop.json.ts index ad48b5dce..f15ba1012 100644 --- a/src/routes/services/[id]/vaultwarden/stop.json.ts +++ b/src/routes/services/[id]/vaultwarden/stop.json.ts @@ -28,7 +28,7 @@ export const post: RequestHandler = async (event) => { console.error(error); } try { - await configureSimpleServiceProxyOff({ domain }); + await configureSimpleServiceProxyOff(fqdn); } catch (error) { console.log(error); } diff --git a/src/routes/services/[id]/vscodeserver/stop.json.ts b/src/routes/services/[id]/vscodeserver/stop.json.ts index f094abc6e..cf748b709 100644 --- a/src/routes/services/[id]/vscodeserver/stop.json.ts +++ b/src/routes/services/[id]/vscodeserver/stop.json.ts @@ -28,7 +28,7 @@ export const post: RequestHandler = async (event) => { console.error(error); } try { - await configureSimpleServiceProxyOff({ domain }); + await configureSimpleServiceProxyOff(fqdn); } catch (error) { console.log(error); } diff --git a/src/routes/services/[id]/wordpress/stop.json.ts b/src/routes/services/[id]/wordpress/stop.json.ts index 759d183b1..800a62de3 100644 --- a/src/routes/services/[id]/wordpress/stop.json.ts +++ b/src/routes/services/[id]/wordpress/stop.json.ts @@ -31,7 +31,7 @@ export const post: RequestHandler = async (event) => { console.error(error); } try { - await configureSimpleServiceProxyOff({ domain }); + await configureSimpleServiceProxyOff(fqdn); } catch (error) { console.log(error); } diff --git a/src/routes/settings/check.json.ts b/src/routes/settings/check.json.ts index 0d099abe6..15d91613f 100644 --- a/src/routes/settings/check.json.ts +++ b/src/routes/settings/check.json.ts @@ -16,7 +16,7 @@ export const post: RequestHandler = async (event) => { return { status: found ? 500 : 200, body: { - error: found && `Domain ${fqdn} is already configured` + error: found && `Domain ${fqdn.replace('www.', '')} is already configured` } }; } catch (error) { diff --git a/src/routes/settings/index.json.ts b/src/routes/settings/index.json.ts index cdf3ee85d..bd365d5e4 100644 --- a/src/routes/settings/index.json.ts +++ b/src/routes/settings/index.json.ts @@ -3,10 +3,8 @@ import { getDomain, getUserDetails } from '$lib/common'; import * as db from '$lib/database'; import { listSettings, ErrorHandler } from '$lib/database'; import { - checkContainer, configureCoolifyProxyOff, configureCoolifyProxyOn, - forceSSLOffApplication, forceSSLOnApplication, reloadHaproxy, removeWwwRedirection, @@ -15,6 +13,7 @@ import { } from '$lib/haproxy'; import { letsEncrypt } from '$lib/letsencrypt'; import type { RequestHandler } from '@sveltejs/kit'; +import { promises as dns } from 'dns'; export const get: RequestHandler = async (event) => { const { status, body } = await getUserDetails(event); @@ -45,14 +44,24 @@ export const del: RequestHandler = async (event) => { if (status === 401) return { status, body }; const { fqdn } = await event.request.json(); - + 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 } }); await configureCoolifyProxyOff(fqdn); await removeWwwRedirection(domain); return { - status: 201 + status: 200, + body: { + message: 'Domain removed', + redirect: ip ? `http://${ip[0]}:3000/settings` : undefined + } }; } catch (error) { return ErrorHandler(error); @@ -69,16 +78,20 @@ export const post: RequestHandler = async (event) => { }; if (status === 401) return { status, body }; - const { fqdn, isRegistrationEnabled } = await event.request.json(); + const { fqdn, isRegistrationEnabled, dualCerts } = await event.request.json(); try { const { id, fqdn: oldFqdn, - isRegistrationEnabled: oldIsRegistrationEnabled + isRegistrationEnabled: oldIsRegistrationEnabled, + dualCerts: oldDualCerts } = await db.listSettings(); if (oldIsRegistrationEnabled !== isRegistrationEnabled) { await db.prisma.setting.update({ where: { id }, data: { isRegistrationEnabled } }); } + if (oldDualCerts !== dualCerts) { + await db.prisma.setting.update({ where: { id }, data: { dualCerts } }); + } if (oldFqdn && oldFqdn !== fqdn) { if (oldFqdn) { const oldDomain = getDomain(oldFqdn); @@ -93,9 +106,9 @@ export const post: RequestHandler = async (event) => { if (domain) { await configureCoolifyProxyOn(fqdn); await setWwwRedirection(fqdn); - if (isHttps && !dev) { + if (isHttps) { await letsEncrypt({ domain, isCoolify: true }); - await forceSSLOnApplication({ domain }); + await forceSSLOnApplication(domain); await reloadHaproxy('/var/run/docker.sock'); } } diff --git a/src/routes/settings/index.svelte b/src/routes/settings/index.svelte index 91bba0e2b..f86af5e4b 100644 --- a/src/routes/settings/index.svelte +++ b/src/routes/settings/index.svelte @@ -30,10 +30,13 @@ import CopyPasswordField from '$lib/components/CopyPasswordField.svelte'; import { browser } from '$app/env'; import { getDomain } from '$lib/components/common'; + import { toast } from '@zerodevx/svelte-toast'; let isRegistrationEnabled = settings.isRegistrationEnabled; + let dualCerts = settings.dualCerts; + let fqdn = settings.fqdn; - let isFqdnSet = settings.fqdn; + let isFqdnSet = !!settings.fqdn; let loading = { save: false, remove: false @@ -43,8 +46,8 @@ if (fqdn) { loading.remove = true; try { - await del(`/settings.json`, { fqdn }); - return window.location.reload(); + const { redirect } = await del(`/settings.json`, { fqdn }); + return redirect ? window.location.replace(redirect) : window.location.reload(); } catch ({ error }) { return errorNotification(error); } finally { @@ -57,7 +60,11 @@ if (name === 'isRegistrationEnabled') { isRegistrationEnabled = !isRegistrationEnabled; } - return await post(`/settings.json`, { isRegistrationEnabled }); + if (name === 'dualCerts') { + dualCerts = !dualCerts; + } + await post(`/settings.json`, { isRegistrationEnabled, dualCerts }); + return toast.push('Settings saved.'); } catch ({ error }) { return errorNotification(error); } @@ -82,15 +89,15 @@
Settings
{#if $session.teamId === '0'} -
+
-
+
Global Settings
{#if isFqdnSet} @@ -103,10 +110,10 @@ > {/if}
-
-
-

Domain (FQDN)

-
+
+
+
Domain (FQDN)
+
-
    +
    + !isFqdnSet && changeSettings('dualCerts')} + /> +
    +
    changeSettings('isRegistrationEnabled')} /> -
+
-
-
-
HAProxy Settings
-
- stats page.`} - /> - -
+
+
Coolify Proxy Settings
+
+ stats page.`} + /> +
+
- -
- -
+
-
+
-
- -
+
diff --git a/src/routes/sources/[id]/_Gitlab.svelte b/src/routes/sources/[id]/_Gitlab.svelte index c95bbb1ba..ba18ea5f2 100644 --- a/src/routes/sources/[id]/_Gitlab.svelte +++ b/src/routes/sources/[id]/_Gitlab.svelte @@ -5,6 +5,7 @@ import { page, session } from '$app/stores'; import { onMount } from 'svelte'; import { post } from '$lib/api'; + import { browser } from '$app/env'; const { id } = $page.params; let loading = false; @@ -120,13 +121,17 @@
For extra security, you can set Expire access tokens! +

Webhook URL: {browser + ? window.location.origin + : ''}/webhooks/gitlab +
But if you will set a custom domain name for Coolify, use that instead." />
diff --git a/src/routes/teams/[id]/index.svelte b/src/routes/teams/[id]/index.svelte index c4f81d31e..487e46486 100644 --- a/src/routes/teams/[id]/index.svelte +++ b/src/routes/teams/[id]/index.svelte @@ -22,21 +22,20 @@