diff --git a/docs/self-host/config-generator.mdx b/docs/self-host/config-generator.mdx new file mode 100644 index 0000000..4addc8e --- /dev/null +++ b/docs/self-host/config-generator.mdx @@ -0,0 +1,7 @@ +--- +sidebar_position: 1 +title: Config Generator +--- +import ConfigGenerator from "../../src/components/ConfigGeneratorFeatures/ConfigGenerator"; + + diff --git a/docusaurus.config.js b/docusaurus.config.js index ca85f77..0afe632 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -113,6 +113,19 @@ const config = { darkTheme: darkCodeTheme, }, }), + plugins: [ + async function TailwindPlugin(context, options) { + return { + name: "docusaurus-tailwindcss", + configurePostCss(postcssOptions) { + // Appends TailwindCSS and AutoPrefixer. + postcssOptions.plugins.push(require("tailwindcss")); + postcssOptions.plugins.push(require("autoprefixer")); + return postcssOptions; + }, + }; + }, + ] }; module.exports = config; diff --git a/package-lock.json b/package-lock.json index a6f1e32..57de72c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,19 +1,25 @@ { - "name": "kleckrelay-docs", - "version": "0.0.0", + "name": "KleckRelay-Docs", + "version": "0.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { - "version": "0.0.0", + "name": "KleckRelay-Docs", + "version": "0.0.1", "dependencies": { "@docusaurus/core": "2.3.1", "@docusaurus/preset-classic": "2.3.1", "@mdx-js/react": "^1.6.22", + "autoprefixer": "^10.4.14", "clsx": "^1.2.1", + "crypto-random-string": "^5.0.0", + "openpgp": "^5.7.0", + "postcss": "^8.4.21", "prism-react-renderer": "^1.3.5", "react": "^17.0.2", - "react-dom": "^17.0.2" + "react-dom": "^17.0.2", + "tailwindcss": "^3.2.7" }, "devDependencies": { "@docusaurus/module-type-aliases": "2.3.1", @@ -3645,6 +3651,35 @@ "acorn": "^8" } }, + "node_modules/acorn-node": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", + "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", + "dependencies": { + "acorn": "^7.0.0", + "acorn-walk": "^7.0.0", + "xtend": "^4.0.2" + } + }, + "node_modules/acorn-node/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-node/node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/acorn-walk": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", @@ -3863,6 +3898,17 @@ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" }, + "node_modules/asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, "node_modules/at-least-node": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", @@ -4059,6 +4105,11 @@ "node": ">=8" } }, + "node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, "node_modules/body-parser": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", @@ -4934,11 +4985,17 @@ } }, "node_modules/crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-5.0.0.tgz", + "integrity": "sha512-KWjTXWwxFd6a94m5CdRGW/t82Tr8DoBc9dNnPCAbFI1EBweN6v1tv8y4Y1m7ndkp/nkIBRxUxAzpaBnR2k3bcQ==", + "dependencies": { + "type-fest": "^2.12.2" + }, "engines": { - "node": ">=8" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/css-declaration-sorter": { @@ -5308,6 +5365,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/defined": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", + "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/del": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", @@ -5405,6 +5470,27 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "node_modules/detective": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz", + "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==", + "dependencies": { + "acorn-node": "^1.8.2", + "defined": "^1.0.0", + "minimist": "^1.2.6" + }, + "bin": { + "detective": "bin/detective.js" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -5416,6 +5502,11 @@ "node": ">=8" } }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + }, "node_modules/dns-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", @@ -8121,6 +8212,14 @@ "node": ">=0.10.0" } }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "engines": { + "node": ">= 6" + } + }, "node_modules/object-inspect": { "version": "1.12.3", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", @@ -8224,6 +8323,17 @@ "opener": "bin/opener-bin.js" } }, + "node_modules/openpgp": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/openpgp/-/openpgp-5.7.0.tgz", + "integrity": "sha512-wchYJQfFbSaocUvUIYqNrWD+lRSmFSG1d3Ak2CHeXFocDSEsf7Uc1zUzHjSdlZPTvGeeXPQ+MJrwVtalL4QCBg==", + "dependencies": { + "asn1.js": "^5.0.0" + }, + "engines": { + "node": ">= 8.0.0" + } + }, "node_modules/p-cancelable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", @@ -8478,6 +8588,14 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -8667,6 +8785,68 @@ "postcss": "^8.2.15" } }, + "node_modules/postcss-import": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz", + "integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", + "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", + "dependencies": { + "lilconfig": "^2.0.5", + "yaml": "^1.10.2" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, "node_modules/postcss-loader": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.0.2.tgz", @@ -8850,6 +9030,24 @@ "postcss": "^8.1.0" } }, + "node_modules/postcss-nested": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.0.tgz", + "integrity": "sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==", + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, "node_modules/postcss-normalize-charset": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", @@ -9283,6 +9481,17 @@ } ] }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -9621,6 +9830,14 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dependencies": { + "pify": "^2.3.0" + } + }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -11014,6 +11231,57 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/tailwindcss": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.7.tgz", + "integrity": "sha512-B6DLqJzc21x7wntlH/GsZwEXTBttVSl1FtCzC8WP4oBc/NKef7kaax5jeihkkCEWc831/5NDJ9gRNDK6NEioQQ==", + "dependencies": { + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "color-name": "^1.1.4", + "detective": "^5.2.1", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.2.12", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "lilconfig": "^2.0.6", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.0.9", + "postcss-import": "^14.1.0", + "postcss-js": "^4.0.0", + "postcss-load-config": "^3.1.4", + "postcss-nested": "6.0.0", + "postcss-selector-parser": "^6.0.11", + "postcss-value-parser": "^4.2.0", + "quick-lru": "^5.1.1", + "resolve": "^1.22.1" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=12.13.0" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/tailwindcss/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -11375,6 +11643,14 @@ "node": ">=8" } }, + "node_modules/unique-string/node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "engines": { + "node": ">=8" + } + }, "node_modules/unist-builder": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-2.0.3.tgz", diff --git a/package.json b/package.json index b972cfa..b9db27e 100644 --- a/package.json +++ b/package.json @@ -18,10 +18,15 @@ "@docusaurus/core": "2.3.1", "@docusaurus/preset-classic": "2.3.1", "@mdx-js/react": "^1.6.22", + "autoprefixer": "^10.4.14", "clsx": "^1.2.1", + "crypto-random-string": "^5.0.0", + "openpgp": "^5.7.0", + "postcss": "^8.4.21", "prism-react-renderer": "^1.3.5", "react": "^17.0.2", - "react-dom": "^17.0.2" + "react-dom": "^17.0.2", + "tailwindcss": "^3.2.7" }, "devDependencies": { "@docusaurus/module-type-aliases": "2.3.1", diff --git a/src/components/ConfigGeneratorFeatures/ConfigGenerator.tsx b/src/components/ConfigGeneratorFeatures/ConfigGenerator.tsx new file mode 100644 index 0000000..7acb34d --- /dev/null +++ b/src/components/ConfigGeneratorFeatures/ConfigGenerator.tsx @@ -0,0 +1,340 @@ +import React, {ReactElement, useState} from "react"; +import * as openpgp from "openpgp/lightweight"; +import cryptoRandomString from "crypto-random-string"; + +export default function ConfigGenerator(): ReactElement { + const [domain, setDomain] = useState(""); + const [mailDomain, setMailDomain] = useState(""); + const [apiDomain, setApiDomain] = useState(""); + const [admins, setAdmins] = useState([]); + const [tempAdminValue, setTempAdminValue] = useState(""); + const [dockerServicesPrefix, setDockerServicesPrefix] = useState("kleckrelay_"); + + const [status, setStatus] = useState<"input" | "loading" | "display">("input"); + + const [privateKeys, setPrivateKeys] = useState<{ + serverKey: string; + dkimKey: string; + kleckSecret: string; + dbPassword: string; + }>(); + + if (status === "loading") { + return ( +

+ Generating keys... +

+ ) + } + + if (status === "display") { + return ( +
+
+

+ Here's your .env file: +

+
+
+
+            
+        {`
+API_DOMAIN=${apiDomain}
+MAIL_DOMAIN=${mailDomain}
+KLECK_SECRET=${privateKeys!.kleckSecret}
+SERVER_PRIVATE_KEY=${privateKeys!.serverKey}
+DKIM_PRIVATE_KEY=${privateKeys!.dkimKey}
+ADMIN_EMAILS=${admins.join(",")}
+DB_URI=postgres://kleckrelay:${privateKeys!.dbPassword}@${dockerServicesPrefix}database/kleckrelay
+        `.trimStart().trimEnd()}
+            
+          
+
+
+

+ Here's your docker-compose.yml file: +

+
+
+
+            
+              {`
+version: "3"
+services:
+  ${dockerServicesPrefix}database:
+    image: postgres:latest
+    container_name: "${dockerServicesPrefix}database"
+    restart: on-failure:5
+ 
+    environment:
+      POSTGRES_USER: kleckrelay
+      POSTGRES_PASSWORD: ${privateKeys!.dbPassword}
+      POSTGRES_DB: kleckrelay
+
+    healthcheck:
+      test: ["CMD-SHELL", "pg_isready -U user -d mail"]
+      interval: 5s
+      timeout: 5s
+      retries: 5
+
+    volumes:
+      - ./db:/var/lib/postgresql/data
+
+  ${dockerServicesPrefix}server:
+    image: myzel394/kleckrelay-server:latest 
+    container_name: "${dockerServicesPrefix}server"
+    restart: on-failure:5
+
+    depends_on:
+      ${dockerServicesPrefix}database:
+         condition: service_healthy
+ 
+    cap_add:
+      - NET_BIND_SERVICE
+      - SYS_PTRACE
+
+    ports:
+      - "25:25"
+      - "587:587"
+
+    volumes:
+      - ./tutorial:/tutorial
+      - ./opendkim_keys:/etc/opendkim/keys
+      - ./certs:/etc/ssl/certs
+
+    env_file:
+      - .env
+
+  ${dockerServicesPrefix}maid:
+    image: myzel394/kleckrelay-maid:latest
+    container_name: "${dockerServicesPrefix}maid"
+    restart: on-failure:5
+ 
+    depends_on:
+      ${dockerServicesPrefix}database:
+        condition: service_healthy
+
+    env_file:
+      - .env
+
+  nginx:
+    image: bunkerity/bunkerweb
+    container_name: nginx
+    restart: on-failure:5
+
+    ports:
+      - "80:80"
+      - "443:443"
+
+    volumes:
+      - ./letsencrypt:/etc/letsencrypt
+
+    environment:
+      - MULTISITE=yes
+      - SERVER_NAME=${domain}
+      - USE_REVERSE_PROXY=yes
+      - DISABLE_DEFAULT_SERVER=yes
+      - AUTO_LETS_ENCRYPT=yes
+      
+      - ${domain}_REVERSE_PROXY_URL=/
+      - ${domain}_REVERSE_PROXY_HOST=${dockerServicesPrefix}server
+      - ${domain}_ALLOWED_METHODS=GET|POST|PUT|PATCH|DELETE|OPTIONS
+      # Security is too strict
+      - ${domain}_BLOCK_ABUSERS=no
+      - ${domain}_USE_BAD_BEHAVIOR=no
+      - ${domain}_REVERSE_PROXY_INTERCEPT_ERRORS=no
+`.trimStart().trimEnd()}
+            
+          
+
+
+ ) + } + + return ( +
+
+
+
+ +
+
+ { + setDomain(event.target.value); + setApiDomain(`api.${event.target.value}`); + setMailDomain(`mail.${event.target.value}`); + }} + /> +
+
+
+
+ +
+
+ setMailDomain(e.target.value)} + /> +
+
+
+
+ +
+
+ setApiDomain(e.target.value)} + /> +
+
+
+
+
+ +
+
+
+
+ setTempAdminValue(e.target.value)} + onKeyDown={event => { + if (event.key === "Enter" || event.key === " " || event.key === "," || event.key === ";") { + event.preventDefault(); + + if (tempAdminValue) { + setAdmins([...admins, tempAdminValue]); + setTempAdminValue(""); + } + } + }} + /> +
+
+ {admins.map((admin, index) => ( + + ))} +
+
+
+
+
+
+ +
+
+ setDockerServicesPrefix(e.target.value)} + /> +
+
+
+ +
+
+ ) +} diff --git a/src/css/custom.css b/src/css/custom.css index 2bc6a4c..64e5ad8 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -3,6 +3,10 @@ * bundles Infima by default. Infima is a CSS framework designed to * work well for content-centric websites. */ +@tailwind base; +@tailwind components; +@tailwind utilities; + /* You can override the default Infima variables here. */ :root {