diff --git a/.gitignore b/.gitignore
index 4bb1c62..d1138a3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -103,3 +103,6 @@ $RECYCLE.BIN/
 # Windows shortcuts
 *.lnk
 
+certs/
+db_config.php
+config.php
\ No newline at end of file
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/TVPNBackend.iml b/.idea/TVPNBackend.iml
new file mode 100644
index 0000000..c956989
--- /dev/null
+++ b/.idea/TVPNBackend.iml
@@ -0,0 +1,8 @@
+
+
+  
+    
+    
+    
+  
+
\ No newline at end of file
diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml
new file mode 100644
index 0000000..b5554f8
--- /dev/null
+++ b/.idea/dataSources.xml
@@ -0,0 +1,12 @@
+
+
+  
+    
+      mariadb
+      true
+      org.mariadb.jdbc.Driver
+      jdbc:mariadb://mariadb.traceyclan.us:3306
+      $ProjectFileDir$
+    
+  
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..876c99f
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+  
+    
+      
+    
+  
+
\ No newline at end of file
diff --git a/.idea/php.xml b/.idea/php.xml
new file mode 100644
index 0000000..7d11e4f
--- /dev/null
+++ b/.idea/php.xml
@@ -0,0 +1,20 @@
+
+
+  
+    
+  
+  
+    
+  
+  
+    
+    
+  
+  
+  
+    
+  
+  
+    
+  
+
\ No newline at end of file
diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml
new file mode 100644
index 0000000..9a220bf
--- /dev/null
+++ b/.idea/sqldialects.xml
@@ -0,0 +1,7 @@
+
+
+  
+    
+    
+  
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+  
+    
+  
+
\ No newline at end of file
diff --git a/api/auth.php b/api/auth.php
new file mode 100644
index 0000000..64bfa5c
--- /dev/null
+++ b/api/auth.php
@@ -0,0 +1,89 @@
+real_escape_string($token);
+    $stmt = $mysqli->prepare("SELECT * FROM users WHERE token = ?");
+    $stmt->bind_param("s", $token);
+
+    $stmt->execute();
+    $result = $stmt->get_result();
+    $response = array();
+    if ($result->num_rows > 0) {
+        $row = $result->fetch_assoc();
+        $response['success'] = "true";
+        $response['message'] = 'Login successful!';
+        $response['token'] = $row['token'];
+        $response['expires'] = $row['expires'];
+    } else {
+        $response['success'] = "false";
+        $response['message'] = 'Invalid token.';
+        $response['token'] = "";
+        $response['expires'] = 0;
+    }
+    // Close connections
+    $stmt->close();
+    $mysqli->close();
+    header('Content-Type: application/json');
+    echo '{"success":"' . $response['success'] . '", "isAuthenticated":' . $response['success'] . ', "token":"'. $response['token'] .'", "expires":' . $response['expires'] . ', "message":"' . $response['message'] . '"' . '}';
+    return;
+}
+
+if (is_null($data)) {
+    header('Content-Type: application/json');
+    http_response_code(412);
+    echo '{"success":"false","message":"No body sent.","token":"","expires": 0,"isAuthenticated":false}';
+    return;
+}
+
+$user = $data['username'];
+$pass = $data['password'];
+
+// Input validation and sanitization
+$user = $mysqli->real_escape_string($user);
+
+// Prepare and bind
+$stmt = $mysqli->prepare("SELECT * FROM users WHERE username = ?");
+$stmt->bind_param("s", $user);
+
+// Execute statement
+$stmt->execute();
+
+// Get result
+$result = $stmt->get_result();
+
+$response = array();
+
+if ($result->num_rows > 0) {
+    $row = $result->fetch_assoc();
+    $hashed_password = $row['passwordHash'];
+    if (password_verify($pass, $hashed_password)) {
+        $response['success'] = "true";
+        $response['message'] = 'Login successful!';
+        $response['token'] = $row['token'];
+        $response['expires'] = $row['expires'];
+    } else {
+        $response['success'] = "false";
+        $response['message'] = 'Invalid username or password.';
+        $response['token'] = "";
+        $response['expires'] = 0;
+    }
+} else {
+    $response['success'] = "false";
+    $response['message'] = 'Invalid username or password.';
+    $response['token'] = "";
+    $response['expires'] = 0;
+}
+
+// Close connections
+$stmt->close();
+$mysqli->close();
+
+// Return JSON response
+header('Content-Type: application/json');
+echo '{"success":"' . $response['success'] . '", "isAuthenticated":' . $response['success'] . ', "token":"'. $response['token'] .'", "expires":' . $response['expires'] . ', "message":"' . $response['message'] . '"' . '}';
+
diff --git a/api/user-info.php b/api/user-info.php
new file mode 100644
index 0000000..85f2b0b
--- /dev/null
+++ b/api/user-info.php
@@ -0,0 +1,49 @@
+real_escape_string($token);
+
+// Prepare and bind
+$stmt = $mysqli->prepare("SELECT * FROM users WHERE token = ?");
+$stmt->bind_param("s", $token);
+
+// Execute statement
+$stmt->execute();
+
+// Get result
+$result = $stmt->get_result();
+
+$response = array();
+
+if ($result->num_rows > 0) {
+    $row = $result->fetch_assoc();
+
+    $response['success'] = "true";
+    $response['message'] = "Success";
+    $response['username'] = $row['username'];
+    $response['email'] = $row['email'];
+} else {
+    $response['success'] = "false";
+    $response['message'] = 'Invalid token.';
+    $response['username'] = "";
+    $response['email'] = "";
+}
+
+// Close connections
+$stmt->close();
+$mysqli->close();
+
+// Return JSON response
+header('Content-Type: application/json');
+echo '{"success":' . $response['success'] . ', "message":"' . $response['message'] . '", "username":"' . $response['username'] . '", "email":"' . $response['email'] . '"}';
diff --git a/assets/css/style.css b/assets/css/style.css
new file mode 100644
index 0000000..22dba22
--- /dev/null
+++ b/assets/css/style.css
@@ -0,0 +1,116 @@
+/* Global container to center the buttons and position tabs at the top */
+body {
+    font-family: Arial, sans-serif;
+    margin: 0;
+    background-color: #f4f4f9;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: flex-start; /* Aligns content to the top */
+    min-height: 100vh;
+}
+
+/* Tab section at the top */
+.tab {
+    width: 100%;
+    display: flex;
+    justify-content: center;
+    background-color: #f1f1f1;
+    padding: 10px 0;
+    border-bottom: 1px solid #ccc;
+}
+
+.tab a {
+    background-color: inherit;
+    border: none;
+    outline: none;
+    cursor: pointer;
+    padding: 14px 16px;
+    transition: 0.3s;
+    text-decoration: none;
+    color: black;
+}
+
+.tab a:hover {
+    background-color: #ddd;
+}
+
+.tab a.active {
+    background-color: #ccc;
+}
+
+/* Container for centering the buttons in the middle of the page */
+.container {
+    text-align: center;
+    width: 300px;
+    padding: 20px;
+    border-radius: 8px;
+    background-color: white;
+    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+    margin-top: 20vh; /* Pushes the container down */
+}
+
+h1 {
+    margin-bottom: 20px;
+    color: #333;
+}
+
+/* Input Group */
+.input-group {
+    margin-bottom: 15px;
+    text-align: left;
+}
+
+.input-group label {
+    display: block;
+    margin-bottom: 5px;
+    color: #333;
+}
+
+.input-group input {
+    width: 100%;
+    padding: 10px;
+    font-size: 16px;
+    border: 1px solid #ccc;
+    border-radius: 4px;
+}
+
+/* Button Styling */
+button {
+    background-color: #4CAF50;
+    color: white;
+    border: none;
+    padding: 15px 32px;
+    margin-top: 10px;
+    font-size: 16px;
+    cursor: pointer;
+    transition: background-color 0.3s;
+    width: 100%;
+}
+
+button:hover {
+    background-color: #45a049;
+}
+
+/* Error Message */
+.error-message {
+    color: red;
+    font-size: 14px;
+    margin-top: 15px;
+}
+
+/* Style for link buttons (can be used globally) */
+.buttons button {
+    background-color: #4CAF50;
+    color: white;
+    border: none;
+    padding: 15px 32px;
+    margin: 10px;
+    font-size: 16px;
+    cursor: pointer;
+    transition: background-color 0.3s;
+}
+
+.buttons button:hover {
+    background-color: #45a049;
+}
diff --git a/authenticate.php b/authenticate.php
new file mode 100644
index 0000000..820f257
--- /dev/null
+++ b/authenticate.php
@@ -0,0 +1,15 @@
+prepare("CREATE TABLE IF NOT EXISTS users(
+    id INTEGER PRIMARY KEY,
+    username TEXT NOT NULL,
+    passwordHash TEXT NOT NULL,
+    email TEXT NOT NULL
+    );");
+
+echo $stmt->execute();
+
+
+$mysqli->close();
\ No newline at end of file
diff --git a/config.php.example b/config.php.example
new file mode 100644
index 0000000..9bf0cda
--- /dev/null
+++ b/config.php.example
@@ -0,0 +1,2 @@
+options(MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, true);
+$mysqli->ssl_set($_SERVER['DOCUMENT_ROOT'] . "/path/to/client-key.pem", $_SERVER['DOCUMENT_ROOT'] . "/path/to/client-cert.pem", $_SERVER['DOCUMENT_ROOT'] . "/path/to/ca-cert.pem", NULL, NULL);
+$mysqli->real_connect($dbHost, $dbUser, $dbPass, $dbName);
\ No newline at end of file
diff --git a/includes/authcheck.php b/includes/authcheck.php
new file mode 100644
index 0000000..a2992be
--- /dev/null
+++ b/includes/authcheck.php
@@ -0,0 +1,22 @@
+
+
diff --git a/includes/utils.php b/includes/utils.php
new file mode 100644
index 0000000..f421725
--- /dev/null
+++ b/includes/utils.php
@@ -0,0 +1,36 @@
+
+
+
+
+
+    
+    
+    Link Buttons Page
+    
+
+
+
+
+    
TVPN
+    
+        
+        
+        
+        
+        
+    
+
 
+
+
+
+
diff --git a/login/authenticate.php b/login/authenticate.php
new file mode 100644
index 0000000..e9046fb
--- /dev/null
+++ b/login/authenticate.php
@@ -0,0 +1,66 @@
+real_escape_string($user);
+
+// Prepare and bind
+$stmt = $mysqli->prepare("SELECT passwordHash FROM users WHERE username = ?");
+$stmt->bind_param("s", $user);
+
+// Execute statement
+$stmt->execute();
+
+// Get result
+$result = $stmt->get_result();
+
+$response = array();
+
+if ($result->num_rows > 0) {
+    $row = $result->fetch_assoc();
+    $hashed_password = $row['passwordHash'];
+    if (password_verify($pass, $hashed_password)) {
+        // Regenerate session ID to prevent session fixation
+        session_regenerate_id(true);
+
+        // Create session
+        $_SESSION['authenticated'] = true;
+        $_SESSION['username'] = $user;
+
+        $response['success'] = true;
+        $response['message'] = 'Login successful!';
+    } else {
+        $response['success'] = false;
+        $response['message'] = 'Invalid username or password.';
+    }
+} else {
+    $response['success'] = false;
+    $response['message'] = 'Invalid username or password.';
+}
+
+// Close connections
+$stmt->close();
+$mysqli->close();
+
+// Return JSON response
+header('Content-Type: application/json');
+echo '{"success":"' . $response['success'] . '","message":"' . $response['message'] . '"' . '}';
+
diff --git a/login/genpass.php b/login/genpass.php
new file mode 100644
index 0000000..93be332
--- /dev/null
+++ b/login/genpass.php
@@ -0,0 +1,2 @@
+
+
+
+
+
+    
+    
+    Login
+    
+
+
+
+
+
+
+
+
diff --git a/login/script.js b/login/script.js
new file mode 100644
index 0000000..b07d26a
--- /dev/null
+++ b/login/script.js
@@ -0,0 +1,36 @@
+document.getElementById('loginForm').addEventListener('submit', function(e) {
+    e.preventDefault();
+
+    const username = document.getElementById('username').value;
+    const password = document.getElementById('password').value;
+
+    const data = {
+        username: username,
+        password: password
+    };
+
+    // Show spinner
+    document.getElementById('spinner').style.display = 'block';
+
+    fetch('authenticate.php', {
+        method: 'POST',
+        headers: {
+            'Content-Type': 'application/json'
+        },
+        body: JSON.stringify(data)
+    })
+        .then(response => response.json())
+        .then(data => {
+            document.getElementById('response').innerText = data.message;
+            // Hide spinner
+            document.getElementById('spinner').style.display = 'none';
+            if (data.success) {
+                window.location.href = '../'; // Redirect on successful login
+            }
+        })
+        .catch((error) => {
+            document.getElementById('response').innerText = 'Error: ' + error;
+            // Hide spinner
+            document.getElementById('spinner').style.display = 'none';
+        });
+});
diff --git a/logout/index.php b/logout/index.php
new file mode 100644
index 0000000..d680048
--- /dev/null
+++ b/logout/index.php
@@ -0,0 +1,24 @@
+
+
+
+
+
+    
+    TVPN Panel
+
+
+
+Hello World!
+
+
\ No newline at end of file
diff --git a/script.js b/script.js
new file mode 100644
index 0000000..da72b95
--- /dev/null
+++ b/script.js
@@ -0,0 +1,3 @@
+function openLink(url) {
+    window.open(url, '_blank');
+}