index.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. <?php
  2. include 'functions.php';
  3. if (file_exists('../../install.lock')) {
  4. exit("The installation has been completed already. Please delete the File 'install.lock' to re-run");
  5. }
  6. function cardStart($title, $subtitle = null)
  7. {
  8. return "
  9. <div class='flex flex-col gap-4 sm:w-auto w-full sm:min-w-[550px] my-6'>
  10. <h1 class='text-center font-bold text-3xl'>CtrlPanel.gg Installation</h1>
  11. <div class='border-4 border-[#2E373B] bg-[#242A2E] rounded-2xl p-6 pt-3 mx-2'>
  12. <h2 class='text-xl text-center mb-2'>$title</h2>"
  13. . (isset($subtitle) ? "<p class='text-neutral-400 mb-1'>$subtitle</p>" : "");
  14. }
  15. ?>
  16. <html>
  17. <head>
  18. <title>CtrlPanel.gg installer Script</title>
  19. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  20. <link href="/install/styles.css" rel="stylesheet">
  21. <style>
  22. body {
  23. color-scheme: dark;
  24. }
  25. .check {
  26. display: flex;
  27. gap: 5px;
  28. align-items: center;
  29. margin-bottom: 5px;
  30. }
  31. .check::before {
  32. width: 20px;
  33. height: 20px;
  34. display: block;
  35. }
  36. .ok {
  37. color: lightgreen;
  38. }
  39. /* Green Checkmark */
  40. .ok::before {
  41. content: url("data:image/svg+xml,%3Csvg fill='none' stroke='lightgreen' stroke-width='1.5' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg' aria-hidden='true'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z'%3E%3C/path%3E%3C/svg%3E");
  42. }
  43. .not-ok {
  44. color: lightcoral;
  45. }
  46. /* Red Cross */
  47. .not-ok::before {
  48. content: url("data:image/svg+xml,%3Csvg fill='none' stroke='lightcoral' stroke-width='1.5' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg' aria-hidden='true'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M9.75 9.75l4.5 4.5m0-4.5l-4.5 4.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z'%3E%3C/path%3E%3C/svg%3E");
  49. }
  50. </style>
  51. </head>
  52. <body class="w-full flex items-center justify-center bg-[#1D2125] text-white">
  53. <?php
  54. // Getting started
  55. if (!isset($_GET['step']) || $_GET['step'] == 1) {
  56. ?>
  57. <?php echo cardStart($title = "Mandatory Checks before Installation", $subtitle = "This installer will lead you through the most crucial Steps of CtrlPanel.gg's setup"); ?>
  58. <ul class="list-none mb-2">
  59. <li class="<?php echo checkHTTPS() == true ? 'ok' : 'not-ok'; ?> check">HTTPS is required</li>
  60. <li class="<?php echo checkWriteable() == true ? 'ok' : 'not-ok'; ?> check">Write-permissions on .env-file</li>
  61. <li class="<?php echo checkPhpVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check"> php
  62. version: <?php echo phpversion(); ?> (minimum required <?php echo $requirements['minPhp']; ?>)</li>
  63. <li class="<?php echo getMySQLVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check"> mysql
  64. version: <?php echo getMySQLVersion(); ?> (minimum required <?php echo $requirements['mysql']; ?>)</li>
  65. <li class="<?php echo count(checkExtensions()) == 0 ? 'ok' : 'not-ok'; ?> check"> Missing
  66. php-extentions: <?php echo count(checkExtensions()) == 0 ? 'none' : '';
  67. foreach (checkExtensions() as $ext) {
  68. echo $ext . ', ';
  69. }
  70. echo count(checkExtensions()) == 0 ? '' : '(Proceed anyway)'; ?></li>
  71. <!-- <li class="<?php echo getZipVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check"> Zip
  72. version: <?php echo getZipVersion(); ?> </li> -->
  73. <li class="<?php echo getGitVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check"> Git
  74. version: <?php echo getGitVersion(); ?> </li>
  75. <li class="<?php echo getTarVersion() === 'OK' ? 'ok' : 'not-ok'; ?> check"> Tar
  76. version: <?php echo getTarVersion(); ?> </li>
  77. </ul>
  78. </div>
  79. <a href="?step=2" class="w-full flex justify-center">
  80. <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500">Lets
  81. go</button>
  82. </a>
  83. <?php
  84. }
  85. // DB Config
  86. if (isset($_GET['step']) && $_GET['step'] == 2) {
  87. echo cardStart($title = "Database Configuration"); ?>
  88. <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkDB">
  89. <?php if (isset($_GET['message'])) {
  90. echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
  91. } ?>
  92. <div class="row">
  93. <div class="col-md-12">
  94. <div class="form-group">
  95. <div class="flex flex-col mb-3">
  96. <label for="databasedriver">Database Driver</label>
  97. <input x-model="databasedriver" id="databasedriver" name="databasedriver" type="text" required value="mysql" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
  98. </div>
  99. </div>
  100. <div class="form-group">
  101. <div class="flex flex-col mb-3">
  102. <label for="databasehost">Database Host</label>
  103. <input x-model="databasehost" id="databasehost" name="databasehost" type="text" required value="127.0.0.1" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
  104. </div>
  105. </div>
  106. <div class="form-group">
  107. <div class="flex flex-col mb-3">
  108. <label for="databaseport">Database Port</label>
  109. <input x-model="databaseport" id="databaseport" name="databaseport" type="number" required value="3306" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
  110. </div>
  111. </div>
  112. <div class="form-group">
  113. <div class="flex flex-col mb-3">
  114. <label for="databaseuser">Database User</label>
  115. <input x-model="databaseuser" id="databaseuser" name="databaseuser" type="text" required value="controlpaneluser" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
  116. </div>
  117. </div>
  118. <div class="form-group">
  119. <div class="flex flex-col mb-3">
  120. <label for="databaseuserpass">Database User Password</label>
  121. <input x-model="databaseuserpass" id="databaseuserpass" name="databaseuserpass" type="text" required class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none ">
  122. </div>
  123. </div>
  124. <div class="form-group">
  125. <div class="flex flex-col">
  126. <label for="database">Database</label>
  127. <input x-model="database" id="database" name="database" type="text" required value="controlpanel" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
  128. </div>
  129. </div>
  130. </div>
  131. </div>
  132. </div>
  133. <div class="w-full flex justify-center ">
  134. <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkDB">Submit</button>
  135. </div>
  136. </form>
  137. </div>
  138. <?php
  139. }
  140. // DB Migration & APP_KEY Generation
  141. if (isset($_GET['step']) && $_GET['step'] == 2.5) { ?>
  142. <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="feedDB">
  143. <?php echo cardStart($title = "Database Migration and Encryption Key Generation", $subtitle = "Lets feed your Database and generate some security keys! <br> This process might take a while. Please do not refresh or close this page!"); ?> <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="feedDB">
  144. <?php if (isset($_GET['message'])) {
  145. echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
  146. } ?>
  147. </div>
  148. <div class="w-full flex justify-center ">
  149. <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="feedDB">Submit</button>
  150. </div>
  151. </form>
  152. <?php
  153. }
  154. // Dashboard Config
  155. if (isset($_GET['step']) && $_GET['step'] == 3) {
  156. echo cardStart($title = "Dashboard Configuration"); ?>
  157. <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkGeneral">
  158. <?php if (isset($_GET['message'])) {
  159. echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
  160. } ?>
  161. <div class="row">
  162. <div class="col-md-12">
  163. <div class="form-group">
  164. <div class="flex flex-col mb-3">
  165. <label for="database">Dashboard URL</label>
  166. <input id="url" name="url" type="text" required value="<?php echo 'https://' . $_SERVER['SERVER_NAME']; ?>" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
  167. </div>
  168. </div>
  169. <div class="form-group">
  170. <div class="flex flex-col">
  171. <label for="name">Host Name</label>
  172. <input id="name" name="name" type="text" required value="" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
  173. </div>
  174. </div>
  175. </div>
  176. </div>
  177. </div>
  178. <div class="w-full flex justify-center ">
  179. <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkGeneral">Submit</button>
  180. </div>
  181. </form>
  182. </div>
  183. <?php
  184. }
  185. // Email Config
  186. if (isset($_GET['step']) && $_GET['step'] == 4) {
  187. echo cardStart($title = "E-Mail Configuration", $subtitle = "This process might take a few seconds when submitted.<br>Please do not refresh or close this page!"); ?>
  188. <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkSMTP">
  189. <?php if (isset($_GET['message'])) {
  190. echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
  191. } ?>
  192. <div class="row">
  193. <div class="col-md-12">
  194. <div class="form-group">
  195. <div class="flex flex-col mb-3">
  196. <label for="method">Your E-Mail Method</label>
  197. <input id="method" name="method" type="text" required value="smtp" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
  198. </div>
  199. </div>
  200. <div class="form-group">
  201. <div class="flex flex-col mb-3">
  202. <label for="host">Your Mailer-Host</label>
  203. <input id="host" name="host" type="text" required value="smtp.google.com" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
  204. </div>
  205. </div>
  206. <div class="form-group">
  207. <div class="flex flex-col mb-3">
  208. <label for="port">Your Mail Port</label>
  209. <input id="port" name="port" type="number" required value="567" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
  210. </div>
  211. </div>
  212. <div class="form-group">
  213. <div class="flex flex-col mb-3">
  214. <label for="user">Your Mail User</label>
  215. <input id="user" name="user" type="text" required value="info@mydomain.com" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
  216. </div>
  217. </div>
  218. <div class="form-group">
  219. <div class="flex flex-col mb-3">
  220. <label for="pass">Your Mail-User Password</label>
  221. <input id="pass" name="pass" type="password" required value="" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
  222. </div>
  223. </div>
  224. <div class="form-group">
  225. <div class="flex flex-col">
  226. <label for="encryption">Your Mail encryption method</label>
  227. <input id="encryption" name="encryption" type="text" required value="tls" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
  228. </div>
  229. </div>
  230. </div>
  231. </div>
  232. </div>
  233. <div class="flex w-full justify-around mt-4 gap-8 px-8">
  234. <button type="submit" class="w-full px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkSMTP">Submit</button>
  235. <a href="?step=5" class="w-full">
  236. <button type="button" class="w-full px-4 py-2 font-bold rounded-md bg-yellow-500/90 hover:bg-yellow-600 shadow-yellow-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-yellow-600">Skip
  237. For Now</button>
  238. </a>
  239. </div>
  240. </form>
  241. </div>
  242. <?php
  243. }
  244. // Pterodactyl Config
  245. if (isset($_GET['step']) && $_GET['step'] == 5) {
  246. echo cardStart($title = "Pterodactyl Configuration", $subtitle = "Lets get some info about your Pterodactyl Installation!"); ?>
  247. <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="checkPtero">
  248. <?php if (isset($_GET['message'])) {
  249. echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
  250. } ?>
  251. <div class="row">
  252. <div class="col-md-12">
  253. <div class="form-group">
  254. <div class="flex flex-col mb-3">
  255. <label for="url">Pterodactyl URL</label>
  256. <input id="url" name="url" type="text" required placeholder="https://ptero.example.com" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
  257. </div>
  258. </div>
  259. <div class="form-group">
  260. <div class="flex flex-col mb-3">
  261. <label for="key">Application API Key</label>
  262. <input id="key" name="key" type="text" required value="" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
  263. <span class="text-neutral-400">[Found at: ptero.example.com/admin/api] <br /> The key needs all
  264. Read & Write permissions! </span>
  265. </div>
  266. </div>
  267. <div class="form-group">
  268. <div class="flex flex-col">
  269. <label for="clientkey">Admin User Client API Key</label>
  270. <input id="clientkey" name="clientkey" type="text" required value="" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
  271. <span class="text-neutral-400">[Found at: ptero.example.com/account/api] <br /> Your Account
  272. needs to be an Admin!</span>
  273. </div>
  274. </div>
  275. </div>
  276. </div>
  277. </div>
  278. <div class="w-full flex justify-center ">
  279. <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="checkPtero">Submit</button>
  280. </div>
  281. </form>
  282. </div>
  283. <?php
  284. }
  285. // Admin Creation Form
  286. if (isset($_GET['step']) && $_GET['step'] == 6) {
  287. echo cardStart($title = "First Admin Creation", $subtitle = "Lets create the first admin user!"); ?>
  288. <form method="POST" enctype="multipart/form-data" class="m-0" action="/install/forms.php" name="createUser">
  289. <?php if (isset($_GET['message'])) {
  290. echo "<p class='not-ok check'>" . $_GET['message'] . '</p>';
  291. } ?>
  292. <div class="form-group">
  293. <div class="flex flex-col mb-3">
  294. <label for="pteroID">Pterodactyl User ID </label>
  295. <input id="pteroID" name="pteroID" type="text" required value="1" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
  296. <span class="text-neutral-400">Found in the users-list on your pterodactyl dashboard</span>
  297. </div>
  298. </div>
  299. <div class="form-group">
  300. <div class="flex flex-col mb-3">
  301. <label for="pass">Password</label>
  302. <input id="pass" name="pass" type="password" required value="" minlength="8" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
  303. <span class="text-neutral-400">This will be your new pterodactyl password aswell!</span>
  304. </div>
  305. </div>
  306. <div class="form-group">
  307. <div class="flex flex-col">
  308. <label for="repass">Confirm Password</label>
  309. <input id="repass" name="repass" type="password" required value="" minlength="8" class="px-2 py-1 bg-[#1D2125] border-2 focus:border-sky-500 box-border rounded-md border-transparent outline-none">
  310. </div>
  311. </div>
  312. </div>
  313. <div class="w-full flex justify-center ">
  314. <button class="w-1/3 min-w-fit mt-2 px-4 py-2 font-bold rounded-md bg-sky-500 hover:bg-sky-600 shadow-sky-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-sky-500" name="createUser">Submit</button>
  315. </div>
  316. </form>
  317. </div>
  318. <?php
  319. }
  320. // Install Finished
  321. if (isset($_GET['step']) && $_GET['step'] == 7) {
  322. $lockfile = fopen('../../install.lock', 'w') or exit('Unable to open file!');
  323. fwrite($lockfile, 'locked');
  324. fclose($lockfile);
  325. echo cardStart($title = "Installation Complete!", $subtitle = "You may navigate to your Dashboard now and log in!");
  326. ?>
  327. <a href="<?php echo getenv('APP_URL'); ?>" class="w-full flex justify-center ">
  328. <button class="mt-2 px-4 py-2 font-bold rounded-md bg-green-500/90 hover:bg-green-600 shadow-green-400 focus:outline-2 focus:outline focus:outline-offset-2 focus:outline-green-500">Lets
  329. Go!</button>
  330. </a>
  331. </div>
  332. </div>
  333. <?php
  334. }
  335. ?>
  336. </body>
  337. </html>