feat: Add ConfigGenerator.tsx

This commit is contained in:
Myzel394 2023-03-16 18:48:05 +01:00
parent 7aa2325a9d
commit 4a15e90aed
6 changed files with 654 additions and 9 deletions

View File

@ -0,0 +1,7 @@
---
sidebar_position: 1
title: Config Generator
---
import ConfigGenerator from "../../src/components/ConfigGeneratorFeatures/ConfigGenerator";
<ConfigGenerator />

View File

@ -113,6 +113,19 @@ const config = {
darkTheme: darkCodeTheme, 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; module.exports = config;

292
package-lock.json generated
View File

@ -1,19 +1,25 @@
{ {
"name": "kleckrelay-docs", "name": "KleckRelay-Docs",
"version": "0.0.0", "version": "0.0.1",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"version": "0.0.0", "name": "KleckRelay-Docs",
"version": "0.0.1",
"dependencies": { "dependencies": {
"@docusaurus/core": "2.3.1", "@docusaurus/core": "2.3.1",
"@docusaurus/preset-classic": "2.3.1", "@docusaurus/preset-classic": "2.3.1",
"@mdx-js/react": "^1.6.22", "@mdx-js/react": "^1.6.22",
"autoprefixer": "^10.4.14",
"clsx": "^1.2.1", "clsx": "^1.2.1",
"crypto-random-string": "^5.0.0",
"openpgp": "^5.7.0",
"postcss": "^8.4.21",
"prism-react-renderer": "^1.3.5", "prism-react-renderer": "^1.3.5",
"react": "^17.0.2", "react": "^17.0.2",
"react-dom": "^17.0.2" "react-dom": "^17.0.2",
"tailwindcss": "^3.2.7"
}, },
"devDependencies": { "devDependencies": {
"@docusaurus/module-type-aliases": "2.3.1", "@docusaurus/module-type-aliases": "2.3.1",
@ -3645,6 +3651,35 @@
"acorn": "^8" "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": { "node_modules/acorn-walk": {
"version": "8.2.0", "version": "8.2.0",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", "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", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
"integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" "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": { "node_modules/at-least-node": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
@ -4059,6 +4105,11 @@
"node": ">=8" "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": { "node_modules/body-parser": {
"version": "1.20.1", "version": "1.20.1",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
@ -4934,11 +4985,17 @@
} }
}, },
"node_modules/crypto-random-string": { "node_modules/crypto-random-string": {
"version": "2.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-5.0.0.tgz",
"integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", "integrity": "sha512-KWjTXWwxFd6a94m5CdRGW/t82Tr8DoBc9dNnPCAbFI1EBweN6v1tv8y4Y1m7ndkp/nkIBRxUxAzpaBnR2k3bcQ==",
"dependencies": {
"type-fest": "^2.12.2"
},
"engines": { "engines": {
"node": ">=8" "node": ">=14.16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/css-declaration-sorter": { "node_modules/css-declaration-sorter": {
@ -5308,6 +5365,14 @@
"url": "https://github.com/sponsors/ljharb" "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": { "node_modules/del": {
"version": "6.1.1", "version": "6.1.1",
"resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", "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", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" "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": { "node_modules/dir-glob": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
@ -5416,6 +5502,11 @@
"node": ">=8" "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": { "node_modules/dns-equal": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
@ -8121,6 +8212,14 @@
"node": ">=0.10.0" "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": { "node_modules/object-inspect": {
"version": "1.12.3", "version": "1.12.3",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
@ -8224,6 +8323,17 @@
"opener": "bin/opener-bin.js" "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": { "node_modules/p-cancelable": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
@ -8478,6 +8588,14 @@
"url": "https://github.com/sponsors/jonschlinkert" "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": { "node_modules/pkg-dir": {
"version": "4.2.0", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
@ -8667,6 +8785,68 @@
"postcss": "^8.2.15" "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": { "node_modules/postcss-loader": {
"version": "7.0.2", "version": "7.0.2",
"resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.0.2.tgz", "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.0.2.tgz",
@ -8850,6 +9030,24 @@
"postcss": "^8.1.0" "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": { "node_modules/postcss-normalize-charset": {
"version": "5.1.0", "version": "5.1.0",
"resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", "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": { "node_modules/randombytes": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "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" "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": { "node_modules/readable-stream": {
"version": "3.6.2", "version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "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" "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": { "node_modules/tapable": {
"version": "2.2.1", "version": "2.2.1",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
@ -11375,6 +11643,14 @@
"node": ">=8" "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": { "node_modules/unist-builder": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-2.0.3.tgz", "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-2.0.3.tgz",

View File

@ -18,10 +18,15 @@
"@docusaurus/core": "2.3.1", "@docusaurus/core": "2.3.1",
"@docusaurus/preset-classic": "2.3.1", "@docusaurus/preset-classic": "2.3.1",
"@mdx-js/react": "^1.6.22", "@mdx-js/react": "^1.6.22",
"autoprefixer": "^10.4.14",
"clsx": "^1.2.1", "clsx": "^1.2.1",
"crypto-random-string": "^5.0.0",
"openpgp": "^5.7.0",
"postcss": "^8.4.21",
"prism-react-renderer": "^1.3.5", "prism-react-renderer": "^1.3.5",
"react": "^17.0.2", "react": "^17.0.2",
"react-dom": "^17.0.2" "react-dom": "^17.0.2",
"tailwindcss": "^3.2.7"
}, },
"devDependencies": { "devDependencies": {
"@docusaurus/module-type-aliases": "2.3.1", "@docusaurus/module-type-aliases": "2.3.1",

View File

@ -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<string>("");
const [mailDomain, setMailDomain] = useState<string>("");
const [apiDomain, setApiDomain] = useState<string>("");
const [admins, setAdmins] = useState<string[]>([]);
const [tempAdminValue, setTempAdminValue] = useState<string>("");
const [dockerServicesPrefix, setDockerServicesPrefix] = useState<string>("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 (
<h3>
Generating keys...
</h3>
)
}
if (status === "display") {
return (
<div className="flex flex-col space-y-5">
<div>
<h2>
Here's your <code>.env</code> file:
</h2>
</div>
<div>
<pre>
<code>
{`
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()}
</code>
</pre>
</div>
<div>
<h2>
Here's your <code>docker-compose.yml</code> file:
</h2>
</div>
<div>
<pre>
<code>
{`
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()}
</code>
</pre>
</div>
</div>
)
}
return (
<div className="flex flex-col space-y-5">
<div className="flex flex-col space-y-3 w-full">
<div className="flex flex-row space-x-2 items-center">
<div className="basis-2/12">
<label htmlFor="domain" className="text-sm font-medium text-gray-700 dark:text-gray-200">
Base Domain
</label>
</div>
<div className="basis-10/12">
<input
id="domain"
className="px-4 py-2 bg-gray-200 border-none rounded-md dark:bg-gray-900"
placeholder="kleckrelay.com"
style={{
borderWidth: 1,
borderColor: "var(--ifm-color-primary-darkest)",
}}
type="text"
value={domain}
onChange={event => {
setDomain(event.target.value);
setApiDomain(`api.${event.target.value}`);
setMailDomain(`mail.${event.target.value}`);
}}
/>
</div>
</div>
<div className="flex flex-row space-x-2 items-center">
<div className="basis-2/12">
<label htmlFor="mailDomain" className="text-sm font-medium text-gray-700 dark:text-gray-200">
Mail Domain
</label>
</div>
<div className="basis-10/12">
<input
id="mailDomain"
className="px-4 py-2 bg-gray-200 border-none rounded-md dark:bg-gray-900"
placeholder="mail.kleckrelay.com"
style={{
borderWidth: 1,
borderColor: "var(--ifm-color-primary-darkest)",
}}
type="text"
value={mailDomain}
onChange={e => setMailDomain(e.target.value)}
/>
</div>
</div>
<div className="flex flex-row space-x-2 items-center">
<div className="basis-2/12">
<label htmlFor="apiDomain" className="text-sm font-medium text-gray-700 dark:text-gray-200">
API Domain
</label>
</div>
<div className="basis-10/12">
<input
id="apiDomain"
className="px-4 py-2 bg-gray-200 border-none rounded-md dark:bg-gray-900"
placeholder="api.kleckrelay.com"
style={{
borderWidth: 1,
borderColor: "var(--ifm-color-primary-darkest)",
}}
type="text"
value={apiDomain}
onChange={e => setApiDomain(e.target.value)}
/>
</div>
</div>
</div>
<div className="flex flex-row space-x-2 items-center">
<div className="basis-2/12">
<label htmlFor="adminInput" className="text-sm font-medium text-gray-700 dark:text-gray-200">
Admins
</label>
</div>
<div className="basis-10/12">
<div className="flex flex-col space-y-2 items-start">
<div>
<input
id="adminInput"
className="px-4 py-2 bg-gray-200 border-none rounded-md dark:bg-gray-900"
placeholder="marvin@kleckrelay.example"
style={{
borderWidth: 1,
borderColor: "var(--ifm-color-primary-darkest)",
}}
type="text"
value={tempAdminValue}
onChange={e => setTempAdminValue(e.target.value)}
onKeyDown={event => {
if (event.key === "Enter" || event.key === " " || event.key === "," || event.key === ";") {
event.preventDefault();
if (tempAdminValue) {
setAdmins([...admins, tempAdminValue]);
setTempAdminValue("");
}
}
}}
/>
</div>
<div className="flex flex-row space-x-2 items-center">
{admins.map((admin, index) => (
<button
key={admin}
aria-label={`Remove ${admin} from admins`}
className="flex flex-row space-x-2 items-center px-3 py-1 border-none cursor-pointer bg-gray-300 dark:bg-gray-800 rounded-full"
onClick={() => {
const newAdmins = [...admins];
newAdmins.splice(index, 1);
setAdmins(newAdmins);
}}
>
<p className="text-sm m-0 font-medium text-gray-700 dark:text-gray-200">{admin}</p>
</button>
))}
</div>
</div>
</div>
</div>
<div className="flex flex-row space-x-2 items-center">
<div className="basis-2/12">
<label htmlFor="dockerServicesPrefix" className="text-sm font-medium text-gray-700 dark:text-gray-200">
Docker Services Prefix
</label>
</div>
<div className="basis-10/12">
<input
id="dockerServicesPrefix"
className="px-4 py-2 bg-gray-200 border-none rounded-md dark:bg-gray-900"
placeholder="my_prefix_"
style={{
borderWidth: 1,
borderColor: "var(--ifm-color-primary-darkest)",
}}
type="text"
value={dockerServicesPrefix}
onChange={e => setDockerServicesPrefix(e.target.value)}
/>
</div>
</div>
<div>
<button
className="px-4 py-2 cursor-pointer border-none rounded-md text-white"
style={{
background: "var(--ifm-color-primary-darkest)",
}}
onClick={async () => {
setStatus("loading");
const {privateKey: serverPrivateKey} = await openpgp.generateKey({
type: "ecc",
format: "armored",
userIDs: [{name: "John Smith", email: "john@example.com"}],
passphrase: "",
rsaBits: 4096,
})
const {privateKey: dkimPrivateKey} = await openpgp.generateKey({
type: "ecc",
format: "armored",
userIDs: [{name: "John Smith", email: "john@example.com"}],
passphrase: "",
rsaBits: 4096,
})
setPrivateKeys({
serverKey: btoa(serverPrivateKey),
dkimKey: btoa(dkimPrivateKey),
kleckSecret: cryptoRandomString({
length: 64,
type: "hex",
}),
dbPassword: cryptoRandomString({
length: 64,
type: "hex",
})
})
setStatus("display");
}}>
Generate config
</button>
</div>
</div>
)
}

View File

@ -3,6 +3,10 @@
* bundles Infima by default. Infima is a CSS framework designed to * bundles Infima by default. Infima is a CSS framework designed to
* work well for content-centric websites. * work well for content-centric websites.
*/ */
@tailwind base;
@tailwind components;
@tailwind utilities;
/* You can override the default Infima variables here. */ /* You can override the default Infima variables here. */
:root { :root {