]> jfr.im git - irc/unrealircd/unrealircd-webpanel.git/blobdiff - settings/install.php
Users: Scratch the "Secure" column, as it's less useful nowadays that
[irc/unrealircd/unrealircd-webpanel.git] / settings / install.php
index 26520270b72f26b1b62a2083a0bb2f1677e773b6..d215ed912dbd601332d7f2e5f30f3542206708ac 100644 (file)
@@ -1,9 +1,44 @@
 <?php
-
-require_once "../common.php";
-
-$uri = $_SERVER['SCRIPT_FILENAME'];
-define('BASE_URL', str_replace("settings/install.php","",$uri));
+/* Log the user out if it was logged in.
+ * This is mostly for devs running the install screen and
+ * fater succeeding the first screen suddenly being logged in
+ * with old credentials/uid weirdness.
+ * Code from example #1 at https://www.php.net/manual/en/function.session-destroy.php
+ */
+session_start();
+$_SESSION = Array();
+if (ini_get("session.use_cookies")) {
+    $params = session_get_cookie_params();
+    setcookie(session_name(), '', time() - 42000,
+        $params["path"], $params["domain"],
+        $params["secure"], $params["httponly"]
+    );
+}
+session_destroy();
+
+require_once "../inc/common.php";
+
+/* Get the base url */
+$uri = $_SERVER['REQUEST_URI'];
+$tok = split($uri, "/");
+$base_url = "";
+for ($i=0; isset($tok[$i]); $i++)
+{
+       if ($tok[$i] == "settings" && strstr($tok[$i + 1], "install.php"))
+       {
+               if ($i)
+               {
+                       for($j=0; $j < $i; $j++)
+                       {
+                               strcat($base_url,$tok[$j]);
+                               strcat($base_url,"/");
+                       }
+               }
+       }
+}
+if (!strlen($base_url))
+       $base_url = "/";
+define('BASE_URL', $base_url);
 
 $writable = (is_writable("../config/")) ? true: false;
 ?>
@@ -15,7 +50,6 @@ $writable = (is_writable("../config/")) ? true: false;
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="HandheldFriendly" content="true">
 
-<link href="<?php echo get_config("base_url"); ?>css/unrealircd-admin.css" rel="stylesheet">
 
 
  <!-- Latest compiled and minified CSS -->
@@ -27,7 +61,7 @@ $writable = (is_writable("../config/")) ? true: false;
 
 <!-- Font Awesome icons -->
 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css">
-<script src="<?php echo get_config("base_url"); ?>js/unrealircd-admin.js"></script>
+<script src="../js/unrealircd-admin.js"></script>
 <title>UnrealIRCd Panel</title>
 <link rel="icon" type="image/x-icon" href="<?php echo get_config("base_url"); ?>img/favicon.ico">
 
@@ -41,101 +75,140 @@ $writable = (is_writable("../config/")) ? true: false;
 
 <body role="document">
 
-    <div class="container"><div class="row"><img src="../img/unreal.jpg" width="35px" height="35px" style="margin-right: 15px"><h3>UnrealIRCd Admin Panel Configuration and Setup</h3></div></div><?php
+               <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>
+<?php
 
        if (file_exists("../config/config.php"))
        {
-               ?><br><div class="container">You're already configured!
+               ?><br><div class="container"><?php Message::Fail("You're already configured!"); ?>
                        <br>
                        <a class="text-center btn btn-primary" href="<?php echo BASE_URL; ?>">Take me home!</a>
                </div>
                <?php
                return;
        }
+       elseif (isset($_POST) && !empty($_POST))
+       {
+               ?><br><div class="container"><?php 
+               $opts = (object)$_POST;
+               /* pre-load the appropriate auth plugin */
+               $auth_method = (isset($opts->auth_method)) ? $opts->auth_method : NULL;
+               $auth_method_name = NULL;
+               switch($auth_method)
+               {
+                       case "sql_db":
+                               $auth_method_name = "SQLDB";
+                               break;
+                       case "file_db":
+                               $auth_method_name = "FileDB";
+                               break;
+               }
+               if ($auth_method)
+                       $am = new Plugin($auth_method);
+               else
+               {
+                       Message::Fail("Invalid parameters");
+                       return;
+               }
+               if ($am->error)
+               {
+                       Message::Fail("Couldn't load plugin \"$auth_method\": $am->error");
+                       return;
+               }
+
+               $config["base_url"] = BASE_URL;
+               $config["plugins"] = Array("$auth_method");
+               if ($auth_method == "sql_db")
+               {
+                       $config["mysql"] = [
+                               "host" => $opts->sql_host,
+                               "database" => $opts->sql_db,
+                               "username" => $opts->sql_user,
+                               "password" => $opts->sql_password,
+                               "table_prefix" => $opts->sql_table_prefix,
+                               ];
+               }
+
+               generate_secrets();
+
+               /* First, write only the config file */
+               write_config_file();
+
+               if ($auth_method == "sql_db")
+               {
+                       sql_db::delete_tables();
+                       if (!sql_db::create_tables())
+                               Message::Fail("Could not create SQL tables");
+               } else if ($auth_method == "file_db")
+               {
+                       file_db::delete_db();
+               }
+
+               $user = [
+                       "user_name" => $opts->account_user,
+                       "user_pass" => $opts->account_password,
+                       "fname" => $opts->account_fname,
+                       "lname" => $opts->account_lname,
+                       "user_bio" => $opts->account_bio,
+                       "email" => $opts->account_email
+               ];
+
+               create_new_user($user);
+               $lkup = new PanelUser($opts->account_user);
+               if (!$lkup->id)
+               {
+                       Message::Fail("Could not create user");
+                       return;
+               }
+               $lkup->add_permission(PERMISSION_MANAGE_USERS);
+
+               /* Now, write all the config (config.php + settings in DB) */
+               write_config();
+               ?>
+               <br>
+               The configuration file has been written. Now, log in to the panel to proceed with the rest of the installation.<br><br>
+               <a class="text-center btn btn-primary" href="<?php echo BASE_URL; ?>">Let's go!</a></div>
+               <?php
+               return;
+       }
 
 ?>
+<style>
+       table tr td {
+               font-style: italic;
+       }
+</style>
+<?php  if (!$writable) { ?>
 <div id="page1" class="container">
        <br>
-       Welcome to the IRC admin panel setup page. This setup process will guide you through the necessary steps to configure your IRC uplink and choose your preferred authentication method.
-       <br><br>
-       The first page will ask you for your UnrealIRCd uplink credentials and will test them to ensure that the connection is successful. This step is crucial for the Admin Panel to function properly.
-       <br><br>
-       Next, you will be asked to choose your preferred authentication method between file-based and SQL. Depending on your choice, additional steps may be required. If you choose SQL, you will be given the option to set up the appropriate tables in the database.
-       <br><br>
-       After that, we'll take you through a short account creation process where you get to create your first account. Once you're setup and logged in, you'll be able to add more users and choose what they can do on your panel.
-       <br><br>
-       Finally, the last page will offer additional options that you can customize according to your preferences. Once you have completed all the necessary steps, your IRC admin panel will be fully configured and ready for use.
-       <br><br>
-       Should you wish to edit your config further, you will find it in the <code>config</code> directory called <code>config.php</code>
-       <br><br>
-       We recommend that you carefully read each page and fill in all the required information accurately to ensure a seamless setup process. Thank you for choosing UnrealIRCd Admin Panel, and we hope you find it useful for managing your server/network.
-    <br><br>
-       
-       <div id="proceed_div" class="text-center"><?php echo ($writable)
-               ? '<div id="page1_proceed" class="btn btn-primary">Proceed</div>'
-               :       'Before we begin, you must let the shell user who owns the webpanel have permission to create files.<br>
-                        <div id="chmod_help" class="btn btn-sm btn-info">Get info</div>'; ?>
-       </div>
+       The admin panel needs to be able to write the config file.<br>
+       Please run: <code>sudo chown <?php echo get_current_user(); ?> <?php echo UPATH; ?> -R</code><br>
+       And after that, refresh this webpage.<br><br>
+       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>.
 </div>
+<?php
+       die;
+} ?>
 
 <!-- Form start -->
-<form>
-<div id="page2" class="container">
-       <h5>RPC Uplink Information</h5>
-       <br>
-       First, let's get you linked with UnrealIRCd.
-       <br><br>
-       If you don't have your credentials, you will need to create them. This is done in your <code>unrealircd.conf</code> <div id="rpc_instructions" class="ml-4 btn btn-sm btn-info">View instructions</div>
-       <br><br>
-       <form>
-       <div class="form-group">
-               <label for="rpc_iphost">Hostname or IP</label>
-               <input name="rpc_iphost" type="text" class="revalidation-needed-rpc form-control" id="rpc_iphost" aria-describedby="hostname_help" placeholder="127.0.0.1">
-               <small id="hostname_help" class="form-text text-muted">The hostname or IP address of your UnrealIRCd server. You should use <code>127.0.0.1</code> for the same machine.</small>
-       </div>
-       <div class="form-group">
-               <label for="rpc_port">Server Port</label>
-               <input name="rpc_port" type="text" class="revalidation-needed-rpc form-control" id="rpc_port" aria-describedby="port_help" placeholder="8600">
-               <small id="port_help" class="form-text text-muted">The port which you designated for RPC connections in your <code>unrealircd.conf</code></small>
-       </div>
-       <div class="form-group form-check">
-               <input name="rpc_ssl" type="checkbox" class="revalidation-needed-rpc form-check-input" id="rpc_ssl">
-               <label class="form-check-label" for="rpc_ssl">My UnrealIRCd server is on a different machine, verify the TLS connection.</label>
-       </div>
-       <div class="form-group">
-               <label for="rpc_username">Username</label>
-               <input name="rpc_user" type="text" class="revalidation-needed-rpc form-control" id="rpc_user" aria-describedby="username_help" placeholder="apiuser">
-               <small id="username_help" class="form-text text-muted">The name of your <code>rpc-user</code> block as defined in your <code>unrealircd.conf</code></small>
-       </div>
-       <div class="form-group">
-               <label for="rpc_password">Password</label>
-               <input name="rpc_password" type="password" class="revalidation-needed-rpc form-control" id="rpc_password">
-       </div>
-       <div class="text-center">
-               <div id="page2_back" class="btn btn-secondary mr-3">Back</div>
-               <div id="page2_next" class="btn btn-primary ml-3" style="display: none">Next</div>
-               <div id="page2_test_connection" class="btn btn-primary ml-3">Test connection</div>
-       </div>
-</div>
-
-
+<form method="post">
 <div id="page3" class="container">
-       <h5>Authentication Method</h5>
+       <h5>Database Backend</h5>
        <br>
-       Here's where you can choose which type of authentication mechanism you want to use behind the scenes.
+       Which database backend would you like to use?
        <br><br>
        Please choose from the available options:
        <div class="form-group">
                <div class="form-check">
-                       <input class="form-check-input" type="radio" name="auth_method" id="file_auth_radio" value="file_auth">
-                       <label class="form-check-label" for="file_auth_radio">
-                               File-based Authentication (Uses local files as a database, no setup needed)
+                       <input class="form-check-input" type="radio" name="auth_method" id="file_db_radio" value="file_db">
+                       <label class="form-check-label" for="file_db_radio">
+                               File-based database (Uses local files as a database, no additional setup needed)
                        </label>
                </div>
                <div class="form-check">
-                       <input class="form-check-input" type="radio" name="auth_method" id="sql_auth_radio" value="sql_auth">
-                       <label class="form-check-label" for="sql_auth_radio">
-                               SQL Authentication (Requires an SQL database)
+                       <input class="form-check-input" type="radio" name="auth_method" id="sql_db_radio" value="sql_db">
+                       <label class="form-check-label" for="sql_db_radio">
+                               SQL Database (Requires an SQL database)
                        </label>
                </div>
        </div>
@@ -143,8 +216,8 @@ $writable = (is_writable("../config/")) ? true: false;
        <div id="sql_form" style="display:none">
                Please enter your SQL information. <div id="sql_instructions" class="ml-4 btn btn-sm btn-info">View instructions</div>
                <div class="form-group">
-                       <label for="sql_iphost">Hostname or IP</label>
-                       <input name="sql_iphost" type="text" class="revalidation-needed-sql form-control" id="sql_iphost" aria-describedby="hostname_help" placeholder="127.0.0.1">
+                       <label for="sql_host">Hostname or IP</label>
+                       <input name="sql_host" type="text" class="revalidation-needed-sql form-control" id="sql_host" aria-describedby="hostname_help" value="127.0.0.1">
                        <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>
                </div>
                <div class="form-group">
@@ -154,16 +227,20 @@ $writable = (is_writable("../config/")) ? true: false;
                </div>
                <div class="form-group">
                        <label for="sql_username">Username</label>
-                       <input name="sql_user" type="text" class="revalidation-needed-sql form-control" id="sql_user" aria-describedby="username_help">
+                       <input name="sql_user" type="text" class="revalidation-needed-sql form-control" id="sql_user" aria-describedby="username_help" autocomplete="new-password">
                        <small id="username_help" class="form-text text-muted">The name of SQL user</small>
                </div>
                <div class="form-group">
                        <label for="sql_password">Password</label>
-                       <input name="sql_password" type="password" class="revalidation-needed-sql form-control" id="sql_password">
+                       <input name="sql_password" type="password" class="revalidation-needed-sql form-control" id="sql_password" autocomplete="new-password">
+               </div>
+               <div class="form-group">
+                       <label for="sql_table_prefix">Table prefix</label>
+                       <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_">
+                       <small id="sql_table_prefix_help" class="form-text text-muted">The prefix for table names (leave blank for none)</small>
                </div>
        </div>
        <div class="text-center">
-               <div id="page3_back" class="btn btn-secondary mr-3">Back</div>
                <div id="page3_next" class="btn btn-primary ml-3">Next</div>
                <div id="page3_test_connection" class="btn btn-primary ml-3" style="display: none">Test connection</div>
        </div>
@@ -171,8 +248,7 @@ $writable = (is_writable("../config/")) ? true: false;
 <div id="page4" class="container" >
        <h5>Create your account</h5>
        <br>
-       Great! Everything looks good so far! Just one last thing before we confirm everything and get you set up.<br>
-       You need an account! Let's make one.<br><br>
+       You need an account, let's make one.<br><br>
        <div class="form-group">
                <label for="account_user" id="userlabel">Pick a username</label>
                <input name="account_user" type="text" class="form-control" id="account_user" aria-describedby="username_help">
@@ -193,7 +269,7 @@ $writable = (is_writable("../config/")) ? true: false;
        </div>
        <div class="form-group">
                <label for="account_fname" id="fnamelabel">First name</label>
-               <input name="account_fname" type="text" class="form-control" id="account_lname">
+               <input name="account_fname" type="text" class="form-control" id="account_fname">
        </div>
        <div class="form-group">
                <label for="account_lname" id="lnamelabel">Last name</label>
@@ -205,12 +281,55 @@ $writable = (is_writable("../config/")) ? true: false;
        </div>
        <div class="text-center">
                <div id="page4_back" class="btn btn-secondary mr-3">Back</div>
-               <div id="page4_next" class="btn btn-primary ml-3">Next</div>
+               <button id="page4_next" type="submit" class="btn btn-primary ml-3">Submit</div>
        </div>
 </div>
-
-<!-- Form end -->
 </form>
+
+<!-- Database overwrite prompt -->
+<div class="modal fade" id="db_overwrite_modal" tabindex="-1" role="dialog" aria-labelledby="confirmModalCenterTitle" aria-hidden="true">
+       <div class="modal-dialog modal-dialog-centered" role="document">
+               <div class="modal-content">
+               <div class="modal-header">
+                       <h5 class="modal-title" id="myModalLabel">Database already contains data</h5>
+                       <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                       <span aria-hidden="true">&times;</span>
+                       </button>
+               </div>
+               <div class="modal-body">
+                       The database already exists and contains data.
+                       If you continue then this existing data will be deleted.
+               </div>
+               <div class="modal-footer">
+                               <button id="CloseButton" type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
+                               <button id="ProceedButton" type="button" class="btn btn-danger" onclick="nextstep();">Continue</button>
+                       </form>
+               </div>
+               </div>
+       </div>
+</div>
+
+<!-- Database error dialog -->
+<div class="modal fade" id="db_error_modal" tabindex="-1" role="dialog" aria-labelledby="confirmModalCenterTitle" aria-hidden="true">
+       <div class="modal-dialog modal-dialog-centered" role="document">
+               <div class="modal-content">
+               <div class="modal-header">
+                       <h5 class="modal-title" id="myModalLabel">Database server error</h5>
+                       <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                       <span aria-hidden="true">&times;</span>
+                       </button>
+               </div>
+               <div class="modal-body" id="db_error_text">
+                       Unable to connect to the database.
+               </div>
+               <div class="modal-footer">
+                               <button id="CloseButton" type="button" class="btn btn-primary" data-dismiss="modal">Ok</button>
+                       </form>
+               </div>
+               </div>
+       </div>
+</div>
+
 <script>
        let BASE_URL = '<?php echo BASE_URL; ?>';
        let chmod_help = document.getElementById('chmod_help');
@@ -220,70 +339,24 @@ $writable = (is_writable("../config/")) ? true: false;
                        window.open("https://www.unrealircd.org/docs/UnrealIRCd_webpanel#Permissions");
                });
 
-       let page1 = document.getElementById('page1');
-       let page2 = document.getElementById('page2');
        let page3 = document.getElementById('page3');
-       let rpc_instructions = document.getElementById('rpc_instructions');
-       let setup_start = document.getElementById('page1_proceed');
-
-       let rpc_host = document.getElementById('rpc_iphost');
-       let rpc_port = document.getElementById('rpc_port');
-       let rpc_user = document.getElementById('rpc_user');
-       let rpc_pass = document.getElementById('rpc_password');
-       let rpc_tls = document.getElementById('rpc_ssl');
-       
-       let page2_back = document.getElementById('page2_back');
-       let page2_next = document.getElementById('page2_next');
-       let test_conn = document.getElementById('page2_test_connection');
+       let page4 = document.getElementById('page4');
 
-       let file_auth_radio = document.getElementById('file_auth_radio');
-       let sql_auth_radio = document.getElementById('sql_auth_radio');
+       let file_db_radio = document.getElementById('file_db_radio');
+       let sql_db_radio = document.getElementById('sql_db_radio');
        let sql_form = document.getElementById('sql_form');
-       let sql_host = document.getElementById('sql_iphost');
+       let sql_host = document.getElementById('sql_host');
        let sql_db = document.getElementById('sql_db');
        let sql_user = document.getElementById('sql_user');
        let sql_pass = document.getElementById('sql_password');
        let sql_test_conn = document.getElementById('page3_test_connection');
-       let page3_back = document.getElementById('page3_back');
        let page3_next = document.getElementById('page3_next');
 
-       
-
        let page4_back = document.getElementById('page4_back');
        let page4_next = document.getElementById('page4_next');
-       
-       page2.style.display = 'none';
-       page3.style.display = 'none';
-
-       rpc_instructions.addEventListener('click', e => {
-               window.open("https://www.unrealircd.org/docs/UnrealIRCd_webpanel#Configuring_UnrealIRCd");
-       });
-
-       setup_start.addEventListener('click', e => {
-               page1.style.display = 'none';
-               page2.style.display = '';
-       });
 
-       page2_back.addEventListener('click', e => {
-               page2.style.display = 'none';
-               page1.style.display = '';
-       });
-       page2_next.addEventListener('click', e => {
-               page2.style.display = 'none';
-               page3.style.display = '';
-               sql_form.style.display = 'none';
-       });
+       page4.style.display = 'none';
 
-       revalidate_rpc = document.querySelectorAll('.revalidation-needed-rpc');
-       for (let i = 0; i < revalidate_rpc.length; i++)
-       {
-               revalidate_rpc[i].addEventListener('input', e => {
-                       page2_next.style.display = 'none';
-                       test_conn.innerHTML = 'Test connection';
-                       test_conn.style.display = '';
-                       test_conn.classList.remove('disabled');
-               });
-       }
        revalidate_sql = document.querySelectorAll('.revalidation-needed-sql');
        for (let i = 0; i < revalidate_sql.length; i++)
        {
@@ -294,59 +367,27 @@ $writable = (is_writable("../config/")) ? true: false;
                        sql_test_conn.classList.remove('disabled');
                });
        }
-       /* The RPC connection tester! */
-       test_conn.addEventListener('click', e => {
-               test_conn.classList.add('disabled');
-               test_conn.innerHTML = "Checking...";
-               fetch(BASE_URL + 'api/installation.php?method=rpc&host='+rpc_host.value+'&port='+rpc_port.value+'&user='+rpc_user.value+'&password='+rpc_pass.value+'&tls_verify='+rpc_tls.checked)
-               .then(response => response.json())
-               .then(data => {
-                       if (data.success)
-                       {
-                               // do something with the JSON data
-                               test_conn.innerHTML = "Success!";
-                               setTimeout(function() {
-                                       test_conn.style.display = 'none';
-                                       page2_next.style.display = '';
-                               }, 2000);
-                       }
-                       else
-                       {
-                               test_conn.innerHTML = "Failed!";
-                               setTimeout(function() {
-                                       test_conn.innerHTML = "Test connection";
-                                       test_conn.classList.remove('disabled');
-                               }, 2000);
-                       }
-               })
-               .catch(error => {
-                       test_conn.innerHTML = "Failed!";
-                               setTimeout(function() {
-                                       test_conn.innerHTML = "Test connection";
-                                       test_conn.classList.remove('disabled');
-                               }, 2000);
-               });
-        });
-
 
-       page3_back.addEventListener('click', e => {
-               page3.style.display = 'none';
-               page2.style.display = '';
-       });
        page3_next.addEventListener('click', e => {
+<?php if (file_exists(UPATH.'/data/database.php')) { ?>
+               $('#db_overwrite_modal').modal();
+               e.preventDefault();
+               return false;
+<?php } ?>
                page3.style.display = 'none';
                page4.style.display = '';
        });
 
-       file_auth_radio.addEventListener('click', e => {
-               if (file_auth_radio.checked){
+       file_db_radio.addEventListener('click', e => {
+               if (file_db_radio.checked){
                        sql_form.style.display = 'none';
                        sql_test_conn.style.display = 'none';
                        page3_next.style.display = '';
                }
        });
-       sql_auth_radio.addEventListener('click', e => {
-               if (!file_auth_radio.checked){
+
+       sql_db_radio.addEventListener('click', e => {
+               if (!file_db_radio.checked){
                        sql_form.style.display = '';
                        sql_test_conn.style.display = '';
                        page3_next.style.display = 'none';
@@ -360,21 +401,31 @@ $writable = (is_writable("../config/")) ? true: false;
        sql_test_conn.addEventListener('click', e => {
                sql_test_conn.classList.add('disabled');
                sql_test_conn.innerHTML = "Checking...";
-               fetch(BASE_URL + 'api/installation.php?method=sql&host='+sql_host.value+'&database='+sql_db.value+'&user='+sql_user.value+'&password='+sql_pass.value)
+               fetch(BASE_URL + 'api/installation.php', {
+                     method:'POST',
+                     headers: {'Content-Type':'application/x-www-form-urlencoded'},
+                     body: 'method=sql&'+
+                           'host='+encodeURIComponent(sql_host.value)+
+                           '&database='+encodeURIComponent(sql_db.value)+
+                           '&user='+encodeURIComponent(sql_user.value)+
+                           '&password='+encodeURIComponent(sql_pass.value)+
+                           '&table_prefix='+encodeURIComponent(sql_table_prefix.value)
+                     })
                .then(response => response.json())
                .then(data => {
                        if (data.success)
                        {
-                               // do something with the JSON data
-                               sql_test_conn.innerHTML = "Success!";
-                               setTimeout(function() {
-                                       sql_test_conn.style.display = 'none';
-                                       page3_next.style.display = '';
-                               }, 2000);
+                               nextstep();
+                       } else
+                       if (data.warn)
+                       {
+                               $('#db_overwrite_modal').modal();
                        }
                        else
                        {
                                sql_test_conn.innerHTML = "Failed!";
+                               $('#db_error_text').html(data.error ? data.error : 'An error occured while connecting to the DB server');
+                               $('#db_error_modal').modal();
                                setTimeout(function() {
                                        sql_test_conn.innerHTML = "Test connection";
                                        sql_test_conn.classList.remove('disabled');
@@ -398,6 +449,9 @@ $writable = (is_writable("../config/")) ? true: false;
        user_pass2 = document.getElementById('account_password_conf');
        user_email_label = document.getElementById('emaillabel');
        user_email = document.getElementById('account_email');
+       user_fname = document.getElementById('account_fname');
+       user_lname = document.getElementById('account_lname');
+       user_bio = document.getElementById('account_bio');
        
        page4_back.addEventListener('click', e => {
                page4.style.display = 'none';
@@ -433,7 +487,6 @@ $writable = (is_writable("../config/")) ? true: false;
                        user_pass2_label.innerHTML = 'Confirm password';
 
                const regex_email = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
-               console.log(user_email.value);
                if (!regex_email.test(user_email.value))
                {
                        user_email_label.innerHTML = 'Email address' + req_not_met;
@@ -443,13 +496,19 @@ $writable = (is_writable("../config/")) ? true: false;
                        user_email_label.innerHTML = 'Email address';
 
                if (errs)
-                       return;
-
+               {
+                       e.preventDefault();
+                       return false;
+               }
 
                page4.style.display = 'none';
-               page5.style.display = '';
        });
 
-
-
+       function nextstep()
+       {
+               $('#db_overwrite_modal').modal('hide');
+               page3.style.display = 'none';
+               page4.style.display = '';
+               window.scrollTo(0,0);
+       }
 </script>
\ No newline at end of file