]> jfr.im git - irc/unrealircd/unrealircd-webpanel.git/blame - settings/install.php
Add sql::table_prefix to first setup screen
[irc/unrealircd/unrealircd-webpanel.git] / settings / install.php
CommitLineData
78069032
VP
1<?php
2
3require_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
9for ($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
23if (!strlen($base_url))
24 $base_url = "/";
25define('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,
ca3c76f7 112 "table_prefix" => $opts->sql_table_prefix,
b41fa16f 113 ];
54b9603c 114 }
b41fa16f 115
54b9603c
BM
116 /* First, write only the config file */
117 write_config_file();
118
119 if ($auth_method == "sql_auth")
120 if (!sql_auth::create_tables())
121 Message::Fail("Could not create SQL tables");
122
123 $user = [
124 "user_name" => $opts->account_user,
125 "user_pass" => $opts->account_password,
126 "fname" => $opts->account_fname,
127 "lname" => $opts->account_lname,
128 "user_bio" => $opts->account_bio,
129 "email" => $opts->account_email
130 ];
131
132 create_new_user($user);
133 $lkup = new PanelUser($opts->account_user);
134 if (!$lkup->id)
135 {
136 Message::Fail("Could not create user");
2dbe2544
VP
137 return;
138 }
54b9603c
BM
139 $lkup->add_permission(PERMISSION_MANAGE_USERS);
140
141 /* Now, write all the config (config.php + settings in DB) */
142 write_config();
143 ?>
144 <br>
145 The configuration file has been written. Now, log in to the panel to proceed with the rest of the installation.<br><br>
146 <a class="text-center btn btn-primary" href="<?php echo BASE_URL; ?>">Let's go!</a></div>
147 <?php
148 return;
9680dd58 149 }
78069032
VP
150
151?>
9680dd58
VP
152<style>
153 table tr td {
154 font-style: italic;
155 }
156</style>
54b9603c 157<?php if (!$writable) { ?>
78069032
VP
158<div id="page1" class="container">
159 <br>
54b9603c
BM
160 The admin panel needs to be able to write the config file.<br>
161 Please run: <code>sudo chown <?php echo get_current_user(); ?> <?php echo UPATH; ?> -R</code><br>
162 And after that, refresh this webpage.<br><br>
163 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 164</div>
54b9603c
BM
165<?php
166 die;
167} ?>
78069032
VP
168
169<!-- Form start -->
2dbe2544 170<form method="post">
78069032 171<div id="page3" class="container">
54b9603c 172 <h5>Authentication Backend</h5>
78069032 173 <br>
54b9603c 174 Which authentication backend would you like to use?
78069032
VP
175 <br><br>
176 Please choose from the available options:
177 <div class="form-group">
178 <div class="form-check">
179 <input class="form-check-input" type="radio" name="auth_method" id="file_auth_radio" value="file_auth">
180 <label class="form-check-label" for="file_auth_radio">
181 File-based Authentication (Uses local files as a database, no setup needed)
182 </label>
183 </div>
184 <div class="form-check">
185 <input class="form-check-input" type="radio" name="auth_method" id="sql_auth_radio" value="sql_auth">
186 <label class="form-check-label" for="sql_auth_radio">
187 SQL Authentication (Requires an SQL database)
188 </label>
189 </div>
190 </div>
191 <br>
192 <div id="sql_form" style="display:none">
193 Please enter your SQL information. <div id="sql_instructions" class="ml-4 btn btn-sm btn-info">View instructions</div>
194 <div class="form-group">
036c24c5
BM
195 <label for="sql_host">Hostname or IP</label>
196 <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
197 <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>
198 </div>
199 <div class="form-group">
200 <label for="sql_db">Database name</label>
f0106ef0 201 <input name="sql_db" type="text" class="revalidation-needed-sql form-control" id="sql_db" aria-describedby="port_help">
78069032
VP
202 <small id="port_help" class="form-text text-muted">The name of the SQL database to write to and read from.</small>
203 </div>
204 <div class="form-group">
205 <label for="sql_username">Username</label>
f0106ef0 206 <input name="sql_user" type="text" class="revalidation-needed-sql form-control" id="sql_user" aria-describedby="username_help">
78069032
VP
207 <small id="username_help" class="form-text text-muted">The name of SQL user</small>
208 </div>
209 <div class="form-group">
210 <label for="sql_password">Password</label>
f0106ef0 211 <input name="sql_password" type="password" class="revalidation-needed-sql form-control" id="sql_password">
78069032 212 </div>
ca3c76f7
BM
213 <div class="form-group">
214 <label for="sql_table_prefix">Table prefix</label>
215 <input name="sql_table_prefix" type="text" class="revalidation-needed-sql form-control" id="sql_table_prefix" aria-describedby="sql_table_prefix_help" value="unreal_">
216 <small id="sql_table_prefix_help" class="form-text text-muted">The prefix for table names (leave blank for none)</small>
217 </div>
78069032
VP
218 </div>
219 <div class="text-center">
78069032
VP
220 <div id="page3_next" class="btn btn-primary ml-3">Next</div>
221 <div id="page3_test_connection" class="btn btn-primary ml-3" style="display: none">Test connection</div>
222 </div>
223</div>
f0106ef0 224<div id="page4" class="container" >
78069032
VP
225 <h5>Create your account</h5>
226 <br>
54b9603c 227 You need an account, let's make one.<br><br>
78069032 228 <div class="form-group">
f0106ef0 229 <label for="account_user" id="userlabel">Pick a username</label>
78069032 230 <input name="account_user" type="text" class="form-control" id="account_user" aria-describedby="username_help">
f0106ef0 231 <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
232 </div>
233 <div class="form-group">
f0106ef0 234 <label for="account_password" id="passlabel">Password</label>
78069032
VP
235 <input name="account_password" type="password" class="form-control" id="account_password" aria-describedby="password_help">
236 <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>
237 </div>
238 <div class="form-group">
f0106ef0 239 <label for="account_password_conf" id="passconflabel">Confirm password</label>
78069032 240 <input name="account_password_conf" type="password" class="form-control" id="account_password_conf">
78069032
VP
241 </div>
242 <div class="form-group">
f0106ef0 243 <label for="account_email" id="emaillabel">Email address</label>
78069032 244 <input name="account_email" type="text" class="form-control" id="account_email" aria-describedby="email_help">
78069032
VP
245 </div>
246 <div class="form-group">
f0106ef0 247 <label for="account_fname" id="fnamelabel">First name</label>
9680dd58 248 <input name="account_fname" type="text" class="form-control" id="account_fname">
78069032
VP
249 </div>
250 <div class="form-group">
f0106ef0 251 <label for="account_lname" id="lnamelabel">Last name</label>
78069032
VP
252 <input name="account_lname" type="text" class="form-control" id="account_lname">
253 </div>
254 <div class="form-group">
f0106ef0 255 <label for="account_bio" id="biolabel">Bio</label>
78069032
VP
256 <textarea name="account_bio" type="text" class="form-control" id="account_bio"></textarea>
257 </div>
258 <div class="text-center">
259 <div id="page4_back" class="btn btn-secondary mr-3">Back</div>
9680dd58
VP
260 <button id="page4_next" type="submit" class="btn btn-primary ml-3">Submit</div>
261 </div>
262</div>
78069032
VP
263</form>
264<script>
265 let BASE_URL = '<?php echo BASE_URL; ?>';
266 let chmod_help = document.getElementById('chmod_help');
267
268 if (chmod_help)
269 chmod_help.addEventListener('click', e => {
270 window.open("https://www.unrealircd.org/docs/UnrealIRCd_webpanel#Permissions");
271 });
272
78069032 273 let page3 = document.getElementById('page3');
9680dd58 274 let page4 = document.getElementById('page4');
78069032
VP
275
276 let file_auth_radio = document.getElementById('file_auth_radio');
277 let sql_auth_radio = document.getElementById('sql_auth_radio');
278 let sql_form = document.getElementById('sql_form');
036c24c5 279 let sql_host = document.getElementById('sql_host');
78069032
VP
280 let sql_db = document.getElementById('sql_db');
281 let sql_user = document.getElementById('sql_user');
282 let sql_pass = document.getElementById('sql_password');
283 let sql_test_conn = document.getElementById('page3_test_connection');
78069032
VP
284 let page3_next = document.getElementById('page3_next');
285
78069032
VP
286 let page4_back = document.getElementById('page4_back');
287 let page4_next = document.getElementById('page4_next');
78069032 288
54b9603c 289 page4.style.display = 'none';
9680dd58 290
f0106ef0
VP
291 revalidate_sql = document.querySelectorAll('.revalidation-needed-sql');
292 for (let i = 0; i < revalidate_sql.length; i++)
293 {
294 revalidate_sql[i].addEventListener('input', e => {
295 page3_next.style.display = 'none';
296 sql_test_conn.innerHTML = 'Test connection';
297 sql_test_conn.style.display = '';
298 sql_test_conn.classList.remove('disabled');
299 });
300 }
9680dd58 301
78069032
VP
302 page3_next.addEventListener('click', e => {
303 page3.style.display = 'none';
304 page4.style.display = '';
305 });
306
307 file_auth_radio.addEventListener('click', e => {
308 if (file_auth_radio.checked){
309 sql_form.style.display = 'none';
310 sql_test_conn.style.display = 'none';
311 page3_next.style.display = '';
312 }
313 });
9680dd58 314
78069032
VP
315 sql_auth_radio.addEventListener('click', e => {
316 if (!file_auth_radio.checked){
317 sql_form.style.display = '';
318 sql_test_conn.style.display = '';
319 page3_next.style.display = 'none';
320 }
321 });
322
323 sql_instructions.addEventListener('click', e => {
324 window.open("https://www.unrealircd.org/docs/UnrealIRCd_webpanel#SQL_Authentication");
325 });
326
327 sql_test_conn.addEventListener('click', e => {
328 sql_test_conn.classList.add('disabled');
329 sql_test_conn.innerHTML = "Checking...";
f0106ef0 330 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
331 .then(response => response.json())
332 .then(data => {
333 if (data.success)
334 {
335 // do something with the JSON data
336 sql_test_conn.innerHTML = "Success!";
337 setTimeout(function() {
338 sql_test_conn.style.display = 'none';
339 page3_next.style.display = '';
340 }, 2000);
341 }
342 else
343 {
344 sql_test_conn.innerHTML = "Failed!";
345 setTimeout(function() {
346 sql_test_conn.innerHTML = "Test connection";
347 sql_test_conn.classList.remove('disabled');
348 }, 2000);
349 }
350 })
351 .catch(error => {
352 sql_test_conn.innerHTML = "Failed!";
353 setTimeout(function() {
354 sql_test_conn.innerHTML = "Test connection";
355 sql_test_conn.classList.remove('disabled');
356 }, 2000);
357 });
f0106ef0 358 });
78069032 359
f0106ef0
VP
360 user_name_label = document.getElementById('userlabel');
361 user_name = document.getElementById('account_user');
362 user_pass_label = document.getElementById('passlabel');
363 user_pass = document.getElementById('account_password');
364 user_pass2_label = document.getElementById('passconflabel');
365 user_pass2 = document.getElementById('account_password_conf');
366 user_email_label = document.getElementById('emaillabel');
367 user_email = document.getElementById('account_email');
9680dd58
VP
368 user_fname = document.getElementById('account_fname');
369 user_lname = document.getElementById('account_lname');
370 user_bio = document.getElementById('account_bio');
f0106ef0 371
78069032
VP
372 page4_back.addEventListener('click', e => {
373 page4.style.display = 'none';
374 page3.style.display = '';
375 });
f0106ef0 376
78069032 377 page4_next.addEventListener('click', e => {
f0106ef0
VP
378
379 /* Form validation */
380 let req_not_met = ' <small style="color:red">Does not meet requirements</small>';
381 let errs = 0;
382 const regex_username = /^[a-zA-Z\d]{3,}$/;
383 if (!regex_username.test(user_name.value))
384 {
385 user_name_label.innerHTML = 'Pick a username!' + req_not_met;
386 errs++;
387 } else
388 user_name_label.innerHTML = 'Pick a username!';
389
390 let regex_pass = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]).{8,}$/;
391 if (!regex_pass.test(user_pass.value))
392 {
393 user_pass_label.innerHTML = 'Password' + req_not_met;
394 errs++;
395 } else
396 user_pass_label.innerHTML = 'Password';
397
398 if (user_pass2.value !== user_pass.value)
399 {
400 user_pass2_label.innerHTML = 'Confirm password <small style="color:red">Passwords do not match</small>';
401 errs++;
402 } else
403 user_pass2_label.innerHTML = 'Confirm password';
404
405 const regex_email = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
f0106ef0
VP
406 if (!regex_email.test(user_email.value))
407 {
408 user_email_label.innerHTML = 'Email address' + req_not_met;
409 errs++;
410 }
411 else
412 user_email_label.innerHTML = 'Email address';
413
414 if (errs)
9680dd58 415 {
54b9603c
BM
416 e.preventDefault();
417 return false;
9680dd58
VP
418 }
419
78069032 420 page4.style.display = 'none';
78069032 421 });
78069032 422</script>