]>
Commit | Line | Data |
---|---|---|
78069032 VP |
1 | <?php |
2 | ||
3 | require_once "../common.php"; | |
4 | ||
9680dd58 | 5 | /* Get the base url */ |
973acaa9 | 6 | $uri = $_SERVER['REQUEST_URI']; |
9680dd58 | 7 | $tok = split($uri, "/"); |
2dbe2544 | 8 | $base_url = ""; |
9680dd58 VP |
9 | for ($i=0; isset($tok[$i]); $i++) |
10 | { | |
2dbe2544 | 11 | if ($tok[$i] == "settings" && strstr($tok[$i + 1], "install.php")) |
9680dd58 | 12 | { |
9680dd58 VP |
13 | if ($i) |
14 | { | |
15 | for($j=0; $j < $i; $j++) | |
16 | { | |
17 | strcat($base_url,$tok[$j]); | |
18 | strcat($base_url,"/"); | |
19 | } | |
20 | } | |
9680dd58 VP |
21 | } |
22 | } | |
2dbe2544 VP |
23 | if (!strlen($base_url)) |
24 | $base_url = "/"; | |
25 | define('BASE_URL', $base_url); | |
26 | ||
78069032 VP |
27 | $writable = (is_writable("../config/")) ? true: false; |
28 | ?> | |
29 | <!DOCTYPE html> | |
30 | <head> | |
31 | <div class="media"> | |
32 | <div class="media-body"> | |
33 | ||
34 | <meta name="viewport" content="width=device-width, initial-scale=1"> | |
35 | <meta name="HandheldFriendly" content="true"> | |
36 | ||
78069032 VP |
37 | |
38 | ||
39 | <!-- Latest compiled and minified CSS --> | |
40 | <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css"> | |
41 | ||
42 | <!-- Font Awesome JS --> | |
43 | <script defer src="https://use.fontawesome.com/releases/v6.2.1/js/solid.js" integrity="sha384-tzzSw1/Vo+0N5UhStP3bvwWPq+uvzCMfrN1fEFe+xBmv1C/AtVX5K0uZtmcHitFZ" crossorigin="anonymous"></script> | |
44 | <script defer src="https://use.fontawesome.com/releases/v6.2.1/js/fontawesome.js" integrity="sha384-6OIrr52G08NpOFSZdxxz1xdNSndlD4vdcf/q2myIUVO0VsqaGHJsB0RaBE01VTOY" crossorigin="anonymous"></script> | |
45 | ||
46 | <!-- Font Awesome icons --> | |
47 | <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css"> | |
2dbe2544 | 48 | <script src="../js/unrealircd-admin.js"></script> |
78069032 VP |
49 | <title>UnrealIRCd Panel</title> |
50 | <link rel="icon" type="image/x-icon" href="<?php echo get_config("base_url"); ?>img/favicon.ico"> | |
51 | ||
52 | <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> | |
53 | <!-- Popper.JS --> | |
54 | <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js" integrity="sha384-cs/chFZiN24E4KMATLdqdvsezGxaGsi4hLGOzlXwp5UZB1LY//20VyM2taTB4QvJ" crossorigin="anonymous"></script> | |
55 | <!-- Bootstrap JS --> | |
56 | <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js" integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm" crossorigin="anonymous"></script> | |
57 | </div></div> | |
58 | </head> | |
59 | ||
60 | <body role="document"> | |
61 | ||
2dbe2544 | 62 | <div class="container mt-4"><div class="row justify-content-center"><img src="../img/unreal.jpg" width="35px" height="35px" style="margin-right: 15px"><h3>UnrealIRCd Admin Panel Configuration and Setup</h3></div></div> |
9680dd58 | 63 | <?php |
78069032 VP |
64 | |
65 | if (file_exists("../config/config.php")) | |
66 | { | |
2dbe2544 | 67 | ?><br><div class="container"><?php Message::Fail("You're already configured!"); ?> |
78069032 VP |
68 | <br> |
69 | <a class="text-center btn btn-primary" href="<?php echo BASE_URL; ?>">Take me home!</a> | |
70 | </div> | |
71 | <?php | |
72 | return; | |
73 | } | |
2dbe2544 | 74 | elseif (isset($_POST) && !empty($_POST)) |
9680dd58 | 75 | { |
2dbe2544 VP |
76 | ?><br><div class="container"><?php |
77 | $opts = (object)$_POST; | |
9680dd58 | 78 | /* pre-load the appropriate auth plugin */ |
9680dd58 | 79 | $auth_method = (isset($opts->auth_method)) ? $opts->auth_method : NULL; |
2dbe2544 VP |
80 | $auth_method_name = NULL; |
81 | switch($auth_method) | |
82 | { | |
83 | case "sql_auth": | |
84 | $auth_method_name = "SQLAuth"; | |
85 | break; | |
86 | case "file_auth": | |
87 | $auth_method_name = "FileAuth"; | |
88 | break; | |
89 | } | |
9680dd58 | 90 | if ($auth_method) |
2dbe2544 | 91 | $am = new Plugin($auth_method); |
9680dd58 | 92 | else |
2dbe2544 VP |
93 | { |
94 | Message::Fail("Invalid parameters"); | |
95 | return; | |
96 | } | |
97 | if ($am->error) | |
98 | { | |
99 | Message::Fail("Couldn't load plugin \"$auth_method\": $am->error"); | |
100 | return; | |
101 | } | |
102 | ||
54b9603c BM |
103 | $config["base_url"] = BASE_URL; |
104 | $config["plugins"] = Array("$auth_method"); | |
105 | if ($auth_method == "sql_auth") | |
2dbe2544 | 106 | { |
54b9603c BM |
107 | $config["mysql"] = [ |
108 | "host" => $opts->sql_host, | |
109 | "database" => $opts->sql_db, | |
110 | "username" => $opts->sql_user, | |
111 | "password" => $opts->sql_password, | |
b41fa16f | 112 | ]; |
54b9603c | 113 | } |
b41fa16f | 114 | |
54b9603c BM |
115 | /* First, write only the config file */ |
116 | write_config_file(); | |
117 | ||
118 | if ($auth_method == "sql_auth") | |
119 | if (!sql_auth::create_tables()) | |
120 | Message::Fail("Could not create SQL tables"); | |
121 | ||
122 | $user = [ | |
123 | "user_name" => $opts->account_user, | |
124 | "user_pass" => $opts->account_password, | |
125 | "fname" => $opts->account_fname, | |
126 | "lname" => $opts->account_lname, | |
127 | "user_bio" => $opts->account_bio, | |
128 | "email" => $opts->account_email | |
129 | ]; | |
130 | ||
131 | create_new_user($user); | |
132 | $lkup = new PanelUser($opts->account_user); | |
133 | if (!$lkup->id) | |
134 | { | |
135 | Message::Fail("Could not create user"); | |
2dbe2544 VP |
136 | return; |
137 | } | |
54b9603c BM |
138 | $lkup->add_permission(PERMISSION_MANAGE_USERS); |
139 | ||
140 | /* Now, write all the config (config.php + settings in DB) */ | |
141 | write_config(); | |
142 | ?> | |
143 | <br> | |
144 | The configuration file has been written. Now, log in to the panel to proceed with the rest of the installation.<br><br> | |
145 | <a class="text-center btn btn-primary" href="<?php echo BASE_URL; ?>">Let's go!</a></div> | |
146 | <?php | |
147 | return; | |
9680dd58 | 148 | } |
78069032 VP |
149 | |
150 | ?> | |
9680dd58 VP |
151 | <style> |
152 | table tr td { | |
153 | font-style: italic; | |
154 | } | |
155 | </style> | |
54b9603c | 156 | <?php if (!$writable) { ?> |
78069032 VP |
157 | <div id="page1" class="container"> |
158 | <br> | |
54b9603c BM |
159 | The admin panel needs to be able to write the config file.<br> |
160 | Please run: <code>sudo chown <?php echo get_current_user(); ?> <?php echo UPATH; ?> -R</code><br> | |
161 | And after that, refresh this webpage.<br><br> | |
162 | If you have any questions about this, read <a href="https://www.unrealircd.org/docs/UnrealIRCd_webpanel#Permissions" target="_blank">the installation manual on permissions</a>. | |
78069032 | 163 | </div> |
54b9603c BM |
164 | <?php |
165 | die; | |
166 | } ?> | |
78069032 VP |
167 | |
168 | <!-- Form start --> | |
2dbe2544 | 169 | <form method="post"> |
78069032 | 170 | <div id="page3" class="container"> |
54b9603c | 171 | <h5>Authentication Backend</h5> |
78069032 | 172 | <br> |
54b9603c | 173 | Which authentication backend would you like to use? |
78069032 VP |
174 | <br><br> |
175 | Please choose from the available options: | |
176 | <div class="form-group"> | |
177 | <div class="form-check"> | |
178 | <input class="form-check-input" type="radio" name="auth_method" id="file_auth_radio" value="file_auth"> | |
179 | <label class="form-check-label" for="file_auth_radio"> | |
180 | File-based Authentication (Uses local files as a database, no setup needed) | |
181 | </label> | |
182 | </div> | |
183 | <div class="form-check"> | |
184 | <input class="form-check-input" type="radio" name="auth_method" id="sql_auth_radio" value="sql_auth"> | |
185 | <label class="form-check-label" for="sql_auth_radio"> | |
186 | SQL Authentication (Requires an SQL database) | |
187 | </label> | |
188 | </div> | |
189 | </div> | |
190 | <br> | |
191 | <div id="sql_form" style="display:none"> | |
192 | Please enter your SQL information. <div id="sql_instructions" class="ml-4 btn btn-sm btn-info">View instructions</div> | |
193 | <div class="form-group"> | |
036c24c5 BM |
194 | <label for="sql_host">Hostname or IP</label> |
195 | <input name="sql_host" type="text" class="revalidation-needed-sql form-control" id="sql_host" aria-describedby="hostname_help" value="127.0.0.1"> | |
78069032 VP |
196 | <small id="hostname_help" class="form-text text-muted">The hostname or IP address of your SQL server. You should use <code>127.0.0.1</code> for the same machine.</small> |
197 | </div> | |
198 | <div class="form-group"> | |
199 | <label for="sql_db">Database name</label> | |
f0106ef0 | 200 | <input name="sql_db" type="text" class="revalidation-needed-sql form-control" id="sql_db" aria-describedby="port_help"> |
78069032 VP |
201 | <small id="port_help" class="form-text text-muted">The name of the SQL database to write to and read from.</small> |
202 | </div> | |
203 | <div class="form-group"> | |
204 | <label for="sql_username">Username</label> | |
f0106ef0 | 205 | <input name="sql_user" type="text" class="revalidation-needed-sql form-control" id="sql_user" aria-describedby="username_help"> |
78069032 VP |
206 | <small id="username_help" class="form-text text-muted">The name of SQL user</small> |
207 | </div> | |
208 | <div class="form-group"> | |
209 | <label for="sql_password">Password</label> | |
f0106ef0 | 210 | <input name="sql_password" type="password" class="revalidation-needed-sql form-control" id="sql_password"> |
78069032 VP |
211 | </div> |
212 | </div> | |
213 | <div class="text-center"> | |
78069032 VP |
214 | <div id="page3_next" class="btn btn-primary ml-3">Next</div> |
215 | <div id="page3_test_connection" class="btn btn-primary ml-3" style="display: none">Test connection</div> | |
216 | </div> | |
217 | </div> | |
f0106ef0 | 218 | <div id="page4" class="container" > |
78069032 VP |
219 | <h5>Create your account</h5> |
220 | <br> | |
54b9603c | 221 | You need an account, let's make one.<br><br> |
78069032 | 222 | <div class="form-group"> |
f0106ef0 | 223 | <label for="account_user" id="userlabel">Pick a username</label> |
78069032 | 224 | <input name="account_user" type="text" class="form-control" id="account_user" aria-describedby="username_help"> |
f0106ef0 | 225 | <small id="username_help" class="form-text text-muted">Pick a username! Please make sure it's at least 3 characters long, contains no spaces, and is made of only letters and numbers.</small> |
78069032 VP |
226 | </div> |
227 | <div class="form-group"> | |
f0106ef0 | 228 | <label for="account_password" id="passlabel">Password</label> |
78069032 VP |
229 | <input name="account_password" type="password" class="form-control" id="account_password" aria-describedby="password_help"> |
230 | <small id="password_help" class="form-text text-muted">Please choose a password that at least 8 characters long, contains at least one uppercase letter, one lowercase letter, one number and one symbol.</small> | |
231 | </div> | |
232 | <div class="form-group"> | |
f0106ef0 | 233 | <label for="account_password_conf" id="passconflabel">Confirm password</label> |
78069032 | 234 | <input name="account_password_conf" type="password" class="form-control" id="account_password_conf"> |
78069032 VP |
235 | </div> |
236 | <div class="form-group"> | |
f0106ef0 | 237 | <label for="account_email" id="emaillabel">Email address</label> |
78069032 | 238 | <input name="account_email" type="text" class="form-control" id="account_email" aria-describedby="email_help"> |
78069032 VP |
239 | </div> |
240 | <div class="form-group"> | |
f0106ef0 | 241 | <label for="account_fname" id="fnamelabel">First name</label> |
9680dd58 | 242 | <input name="account_fname" type="text" class="form-control" id="account_fname"> |
78069032 VP |
243 | </div> |
244 | <div class="form-group"> | |
f0106ef0 | 245 | <label for="account_lname" id="lnamelabel">Last name</label> |
78069032 VP |
246 | <input name="account_lname" type="text" class="form-control" id="account_lname"> |
247 | </div> | |
248 | <div class="form-group"> | |
f0106ef0 | 249 | <label for="account_bio" id="biolabel">Bio</label> |
78069032 VP |
250 | <textarea name="account_bio" type="text" class="form-control" id="account_bio"></textarea> |
251 | </div> | |
252 | <div class="text-center"> | |
253 | <div id="page4_back" class="btn btn-secondary mr-3">Back</div> | |
9680dd58 VP |
254 | <button id="page4_next" type="submit" class="btn btn-primary ml-3">Submit</div> |
255 | </div> | |
256 | </div> | |
78069032 VP |
257 | </form> |
258 | <script> | |
259 | let BASE_URL = '<?php echo BASE_URL; ?>'; | |
260 | let chmod_help = document.getElementById('chmod_help'); | |
261 | ||
262 | if (chmod_help) | |
263 | chmod_help.addEventListener('click', e => { | |
264 | window.open("https://www.unrealircd.org/docs/UnrealIRCd_webpanel#Permissions"); | |
265 | }); | |
266 | ||
78069032 | 267 | let page3 = document.getElementById('page3'); |
9680dd58 | 268 | let page4 = document.getElementById('page4'); |
78069032 VP |
269 | |
270 | let file_auth_radio = document.getElementById('file_auth_radio'); | |
271 | let sql_auth_radio = document.getElementById('sql_auth_radio'); | |
272 | let sql_form = document.getElementById('sql_form'); | |
036c24c5 | 273 | let sql_host = document.getElementById('sql_host'); |
78069032 VP |
274 | let sql_db = document.getElementById('sql_db'); |
275 | let sql_user = document.getElementById('sql_user'); | |
276 | let sql_pass = document.getElementById('sql_password'); | |
277 | let sql_test_conn = document.getElementById('page3_test_connection'); | |
78069032 VP |
278 | let page3_next = document.getElementById('page3_next'); |
279 | ||
78069032 VP |
280 | let page4_back = document.getElementById('page4_back'); |
281 | let page4_next = document.getElementById('page4_next'); | |
78069032 | 282 | |
54b9603c | 283 | page4.style.display = 'none'; |
9680dd58 | 284 | |
f0106ef0 VP |
285 | revalidate_sql = document.querySelectorAll('.revalidation-needed-sql'); |
286 | for (let i = 0; i < revalidate_sql.length; i++) | |
287 | { | |
288 | revalidate_sql[i].addEventListener('input', e => { | |
289 | page3_next.style.display = 'none'; | |
290 | sql_test_conn.innerHTML = 'Test connection'; | |
291 | sql_test_conn.style.display = ''; | |
292 | sql_test_conn.classList.remove('disabled'); | |
293 | }); | |
294 | } | |
9680dd58 | 295 | |
78069032 VP |
296 | page3_next.addEventListener('click', e => { |
297 | page3.style.display = 'none'; | |
298 | page4.style.display = ''; | |
299 | }); | |
300 | ||
301 | file_auth_radio.addEventListener('click', e => { | |
302 | if (file_auth_radio.checked){ | |
303 | sql_form.style.display = 'none'; | |
304 | sql_test_conn.style.display = 'none'; | |
305 | page3_next.style.display = ''; | |
306 | } | |
307 | }); | |
9680dd58 | 308 | |
78069032 VP |
309 | sql_auth_radio.addEventListener('click', e => { |
310 | if (!file_auth_radio.checked){ | |
311 | sql_form.style.display = ''; | |
312 | sql_test_conn.style.display = ''; | |
313 | page3_next.style.display = 'none'; | |
314 | } | |
315 | }); | |
316 | ||
317 | sql_instructions.addEventListener('click', e => { | |
318 | window.open("https://www.unrealircd.org/docs/UnrealIRCd_webpanel#SQL_Authentication"); | |
319 | }); | |
320 | ||
321 | sql_test_conn.addEventListener('click', e => { | |
322 | sql_test_conn.classList.add('disabled'); | |
323 | sql_test_conn.innerHTML = "Checking..."; | |
f0106ef0 | 324 | fetch(BASE_URL + 'api/installation.php?method=sql&host='+sql_host.value+'&database='+sql_db.value+'&user='+sql_user.value+'&password='+sql_pass.value) |
78069032 VP |
325 | .then(response => response.json()) |
326 | .then(data => { | |
327 | if (data.success) | |
328 | { | |
329 | // do something with the JSON data | |
330 | sql_test_conn.innerHTML = "Success!"; | |
331 | setTimeout(function() { | |
332 | sql_test_conn.style.display = 'none'; | |
333 | page3_next.style.display = ''; | |
334 | }, 2000); | |
335 | } | |
336 | else | |
337 | { | |
338 | sql_test_conn.innerHTML = "Failed!"; | |
339 | setTimeout(function() { | |
340 | sql_test_conn.innerHTML = "Test connection"; | |
341 | sql_test_conn.classList.remove('disabled'); | |
342 | }, 2000); | |
343 | } | |
344 | }) | |
345 | .catch(error => { | |
346 | sql_test_conn.innerHTML = "Failed!"; | |
347 | setTimeout(function() { | |
348 | sql_test_conn.innerHTML = "Test connection"; | |
349 | sql_test_conn.classList.remove('disabled'); | |
350 | }, 2000); | |
351 | }); | |
f0106ef0 | 352 | }); |
78069032 | 353 | |
f0106ef0 VP |
354 | user_name_label = document.getElementById('userlabel'); |
355 | user_name = document.getElementById('account_user'); | |
356 | user_pass_label = document.getElementById('passlabel'); | |
357 | user_pass = document.getElementById('account_password'); | |
358 | user_pass2_label = document.getElementById('passconflabel'); | |
359 | user_pass2 = document.getElementById('account_password_conf'); | |
360 | user_email_label = document.getElementById('emaillabel'); | |
361 | user_email = document.getElementById('account_email'); | |
9680dd58 VP |
362 | user_fname = document.getElementById('account_fname'); |
363 | user_lname = document.getElementById('account_lname'); | |
364 | user_bio = document.getElementById('account_bio'); | |
f0106ef0 | 365 | |
78069032 VP |
366 | page4_back.addEventListener('click', e => { |
367 | page4.style.display = 'none'; | |
368 | page3.style.display = ''; | |
369 | }); | |
f0106ef0 | 370 | |
78069032 | 371 | page4_next.addEventListener('click', e => { |
f0106ef0 VP |
372 | |
373 | /* Form validation */ | |
374 | let req_not_met = ' <small style="color:red">Does not meet requirements</small>'; | |
375 | let errs = 0; | |
376 | const regex_username = /^[a-zA-Z\d]{3,}$/; | |
377 | if (!regex_username.test(user_name.value)) | |
378 | { | |
379 | user_name_label.innerHTML = 'Pick a username!' + req_not_met; | |
380 | errs++; | |
381 | } else | |
382 | user_name_label.innerHTML = 'Pick a username!'; | |
383 | ||
384 | let regex_pass = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]).{8,}$/; | |
385 | if (!regex_pass.test(user_pass.value)) | |
386 | { | |
387 | user_pass_label.innerHTML = 'Password' + req_not_met; | |
388 | errs++; | |
389 | } else | |
390 | user_pass_label.innerHTML = 'Password'; | |
391 | ||
392 | if (user_pass2.value !== user_pass.value) | |
393 | { | |
394 | user_pass2_label.innerHTML = 'Confirm password <small style="color:red">Passwords do not match</small>'; | |
395 | errs++; | |
396 | } else | |
397 | user_pass2_label.innerHTML = 'Confirm password'; | |
398 | ||
399 | const regex_email = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; | |
f0106ef0 VP |
400 | if (!regex_email.test(user_email.value)) |
401 | { | |
402 | user_email_label.innerHTML = 'Email address' + req_not_met; | |
403 | errs++; | |
404 | } | |
405 | else | |
406 | user_email_label.innerHTML = 'Email address'; | |
407 | ||
408 | if (errs) | |
9680dd58 | 409 | { |
54b9603c BM |
410 | e.preventDefault(); |
411 | return false; | |
9680dd58 VP |
412 | } |
413 | ||
78069032 | 414 | page4.style.display = 'none'; |
78069032 | 415 | }); |
78069032 | 416 | </script> |