mirror of
				https://github.com/billz/raspap-webgui.git
				synced 2025-03-01 10:31:47 +00:00 
			
		
		
		
	Merge pull request #1735 from RaspAP/feat/session-manager
Feature: Session manager & dedicated login
This commit is contained in:
		| @@ -1,6 +1,7 @@ | ||||
| <?php | ||||
|  | ||||
| require '../../includes/csrf.php'; | ||||
| require_once '../../includes/session.php'; | ||||
| require_once '../../includes/config.php'; | ||||
| require_once '../../src/RaspAP/Auth/HTTPAuth.php'; | ||||
| require_once '../../includes/authenticate.php'; | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| <?php | ||||
|  | ||||
| require '../../includes/csrf.php'; | ||||
| require_once '../../includes/session.php'; | ||||
| require_once '../../includes/config.php'; | ||||
| require_once '../../src/RaspAP/Auth/HTTPAuth.php'; | ||||
| require_once '../../includes/authenticate.php'; | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| <?php | ||||
|  | ||||
| require '../../includes/csrf.php'; | ||||
| require_once '../../includes/session.php'; | ||||
| require_once '../../includes/config.php'; | ||||
| require_once '../../src/RaspAP/Auth/HTTPAuth.php'; | ||||
| require_once '../../includes/authenticate.php'; | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| <?php | ||||
|  | ||||
| require '../../includes/csrf.php'; | ||||
| require_once '../../includes/session.php'; | ||||
| require_once '../../includes/config.php'; | ||||
| require_once '../../src/RaspAP/Auth/HTTPAuth.php'; | ||||
| require_once '../../includes/authenticate.php'; | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| <?php | ||||
|  | ||||
| require_once '../../includes/config.php'; | ||||
| require_once '../../includes/session.php'; | ||||
| require_once '../../src/RaspAP/Auth/HTTPAuth.php'; | ||||
| require_once '../../includes/authenticate.php'; | ||||
| require_once '../../includes/session.php'; | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| <?php | ||||
|  | ||||
| require '../../includes/csrf.php'; | ||||
| require_once '../../includes/session.php'; | ||||
| require_once '../../includes/config.php'; | ||||
| require_once '../../src/RaspAP/Auth/HTTPAuth.php'; | ||||
| require_once '../../includes/authenticate.php'; | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| <?php | ||||
|  | ||||
| require '../../includes/csrf.php'; | ||||
| require_once '../../includes/session.php'; | ||||
| require_once '../../includes/config.php'; | ||||
| require_once '../../src/RaspAP/Auth/HTTPAuth.php'; | ||||
| require_once '../../includes/authenticate.php'; | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| <?php | ||||
|  | ||||
| require '../../includes/csrf.php'; | ||||
| require_once '../../includes/session.php'; | ||||
| require_once '../../includes/config.php'; | ||||
| require_once '../../src/RaspAP/Auth/HTTPAuth.php'; | ||||
| require_once '../../src/RaspAP/Parsers/IwParser.php'; | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <?php | ||||
|  | ||||
| require '../../includes/csrf.php'; | ||||
|  | ||||
| require_once '../../includes/session.php'; | ||||
| require_once '../../includes/functions.php'; | ||||
| require_once '../../includes/config.php'; | ||||
| require_once '../../src/RaspAP/Auth/HTTPAuth.php'; | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| <?php | ||||
|  | ||||
| require '../../includes/csrf.php'; | ||||
| require_once '../../includes/session.php'; | ||||
| require_once '../../includes/config.php'; | ||||
| require_once '../../src/RaspAP/Auth/HTTPAuth.php'; | ||||
| require_once '../../includes/authenticate.php'; | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| <?php | ||||
|  | ||||
| require '../../includes/csrf.php'; | ||||
| require_once '../../includes/session.php'; | ||||
| require_once '../../includes/config.php'; | ||||
| require_once '../../src/RaspAP/Auth/HTTPAuth.php'; | ||||
| require_once '../../includes/authenticate.php'; | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| <?php | ||||
|  | ||||
| require '../../includes/csrf.php'; | ||||
| require_once '../../includes/session.php'; | ||||
| require_once '../../includes/config.php'; | ||||
| require_once '../../src/RaspAP/Auth/HTTPAuth.php'; | ||||
| require_once '../../includes/authenticate.php'; | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| <?php | ||||
|  | ||||
| require '../../includes/csrf.php'; | ||||
| require_once '../../includes/session.php'; | ||||
| require_once '../../includes/config.php'; | ||||
| require_once '../../src/RaspAP/Auth/HTTPAuth.php'; | ||||
| require_once '../../includes/authenticate.php'; | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| <?php | ||||
|  | ||||
| require '../../includes/csrf.php'; | ||||
| require_once '../../includes/session.php'; | ||||
| require_once '../../includes/config.php'; | ||||
| require_once '../../src/RaspAP/Auth/HTTPAuth.php'; | ||||
| require_once '../../includes/authenticate.php'; | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| <?php | ||||
|  | ||||
| require '../../includes/csrf.php'; | ||||
| require_once '../../includes/session.php'; | ||||
| require_once '../../includes/config.php'; | ||||
| require_once '../../src/RaspAP/Auth/HTTPAuth.php'; | ||||
| require_once '../../includes/authenticate.php'; | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| <?php | ||||
|  | ||||
| require '../../includes/csrf.php'; | ||||
| require_once '../../includes/session.php'; | ||||
| require_once '../../includes/config.php'; | ||||
| require_once '../../src/RaspAP/Auth/HTTPAuth.php'; | ||||
| require_once '../../includes/authenticate.php'; | ||||
|   | ||||
							
								
								
									
										32
									
								
								ajax/session/do_check_session.php
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										32
									
								
								ajax/session/do_check_session.php
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| <?php | ||||
|  | ||||
| require '../../includes/csrf.php'; | ||||
| require_once '../../includes/session.php'; | ||||
| require_once '../../includes/config.php'; | ||||
| require_once '../../src/RaspAP/Auth/HTTPAuth.php'; | ||||
| require_once '../../includes/authenticate.php'; | ||||
|  | ||||
| $lastActivity = $_SESSION['lastActivity'] ?? time(); | ||||
| $sessionLifetime = time() - $lastActivity; | ||||
| $status = $sessionLifetime >= RASPI_SESSION_TIMEOUT ? 'session_expired' : 'active'; | ||||
|  | ||||
| if ($status = 'session_expired') { | ||||
|     session_unset(); // unset all session variables | ||||
|     session_destroy(); // destroy the session | ||||
| } | ||||
|  | ||||
| // send response | ||||
| header('Content-Type: application/json'); | ||||
| header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0'); | ||||
| header('Expires: Thu, 01 Jan 1970 00:00:00 GMT'); | ||||
| header('Pragma: no-cache'); | ||||
|  | ||||
| $response = [ | ||||
|     'status' => $status, | ||||
|     'last_activity' => $lastActivity, | ||||
|     'session_lifetime' => $sessionLifetime | ||||
| ]; | ||||
|  | ||||
| echo json_encode($response); | ||||
| exit(); | ||||
|  | ||||
| @@ -1,6 +1,7 @@ | ||||
| <?php | ||||
|  | ||||
| require '../../includes/csrf.php'; | ||||
| require_once '../../includes/session.php'; | ||||
| require_once '../../includes/config.php'; | ||||
| require_once '../../src/RaspAP/Auth/HTTPAuth.php'; | ||||
| require_once '../../includes/authenticate.php'; | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| <?php | ||||
|  | ||||
| require '../../includes/csrf.php'; | ||||
| require_once '../../includes/session.php'; | ||||
| require_once '../../includes/config.php'; | ||||
| require_once '../../includes/defaults.php'; | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| <?php | ||||
|  | ||||
| require '../../includes/csrf.php'; | ||||
| require_once '../../includes/session.php'; | ||||
| require_once '../../includes/config.php'; | ||||
| require_once '../../src/RaspAP/Auth/HTTPAuth.php'; | ||||
| require_once '../../includes/authenticate.php'; | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| <?php | ||||
|  | ||||
| require '../../includes/csrf.php'; | ||||
| require_once '../../includes/session.php'; | ||||
| require_once '../../includes/config.php'; | ||||
| require_once '../../src/RaspAP/Auth/HTTPAuth.php'; | ||||
| require_once '../../includes/authenticate.php'; | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| <?php | ||||
|  | ||||
| require '../../includes/csrf.php'; | ||||
| require_once '../../includes/session.php'; | ||||
| require_once '../../includes/config.php'; | ||||
| require_once '../../src/RaspAP/Auth/HTTPAuth.php'; | ||||
| require_once '../../includes/authenticate.php'; | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| <?php | ||||
|  | ||||
| require_once '../../includes/config.php'; | ||||
| require_once '../../includes/session.php'; | ||||
| require_once '../../src/RaspAP/Auth/HTTPAuth.php'; | ||||
| require_once '../../includes/authenticate.php'; | ||||
|  | ||||
|   | ||||
| @@ -10,6 +10,7 @@ License: GNU General Public License v3.0 | ||||
|   --raspap-content-main: #495057; | ||||
|   --raspap-text-muted: #858796; | ||||
|   --raspap-brand-color: #2b8080; | ||||
|   --raspap-offwhite: #faf9f6; | ||||
| } | ||||
|  | ||||
| a { | ||||
| @@ -306,16 +307,16 @@ button > i.fas { | ||||
|  | ||||
| /* Font Awesome 5 brands */ | ||||
| .fa-reddit { | ||||
|     color: #ff4500; | ||||
|   color: #ff4500; | ||||
| } | ||||
| .fa-twitter { | ||||
|     color: #55acee | ||||
|   color: #55acee | ||||
| } | ||||
| .fa-discord { | ||||
|     color: #7289da | ||||
|   color: #7289da | ||||
| } | ||||
| .fa-github { | ||||
|     color: #151b23 | ||||
|   color: #151b23 | ||||
| } | ||||
|  | ||||
| @keyframes heart { | ||||
| @@ -332,3 +333,47 @@ button > i.fas { | ||||
|   animation: heart 1000ms infinite; | ||||
| } | ||||
|  | ||||
| #modal-admin-login .modal-content { | ||||
|   background: radial-gradient(circle at 120% -20%, #032626, #052c2c, #073232, #0a3838, #0d3f3f, #114545, #144c4c); | ||||
|   align-items: center; | ||||
| } | ||||
|  | ||||
| #modal-admin-login .modal-body { | ||||
|   min-width: 330px; | ||||
| } | ||||
|  | ||||
| .login-brand { | ||||
|   color: var(--raspap-theme-color); | ||||
|   filter: brightness(150%); | ||||
| } | ||||
|  | ||||
| .admin-login { | ||||
|   color: var(--raspap-offwhite); | ||||
|   font-size: 1.2em | ||||
| } | ||||
|  | ||||
| .btn-admin-login { | ||||
|   color: var(--raspap-offwhite); | ||||
|   background-color: var(--raspap-theme-color); | ||||
| } | ||||
|  | ||||
| .btn-admin-login:hover { | ||||
|   color: var(--raspap-offwhite); | ||||
|   background-color: #236969; | ||||
| } | ||||
|  | ||||
| .no-right-radius { | ||||
|   border-top-right-radius: 0 !important; | ||||
|   border-bottom-right-radius: 0 !important; | ||||
| } | ||||
|  | ||||
| .btn-passwd-append { | ||||
|   border: 1px solid #ced4da; | ||||
| } | ||||
|  | ||||
| #passwd-toggle:active, | ||||
| #passwd-toggle:hover, | ||||
| #passwd-toggle:focus { | ||||
|   border: 1px solid #ced4da; | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										0
									
								
								app/img/raspAP-logo.php
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								app/img/raspAP-logo.php
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								app/img/wg-qr-code.php
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								app/img/wg-qr-code.php
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								app/img/wifi-qr-code.php
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								app/img/wifi-qr-code.php
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @@ -671,6 +671,44 @@ window.addEventListener('load', function() { | ||||
|     }); | ||||
| }, false); | ||||
|  | ||||
| let sessionCheckInterval = setInterval(checkSession, 5000); | ||||
|  | ||||
| function checkSession() { | ||||
|     // skip session check if on login page | ||||
|     if (window.location.pathname === '/login') { | ||||
|         return; | ||||
|     } | ||||
|     var csrfToken = $('meta[name=csrf_token]').attr('content'); | ||||
|     $.post('ajax/session/do_check_session.php',{'csrf_token': csrfToken},function (data) { | ||||
|         if (data.status === 'session_expired') { | ||||
|             clearInterval(sessionCheckInterval); | ||||
|             showSessionExpiredModal(); | ||||
|         } | ||||
|     }).fail(function (jqXHR, status, err) { | ||||
|         console.error("Error checking session status:", status, err); | ||||
|     }); | ||||
| } | ||||
|  | ||||
| function showSessionExpiredModal() { | ||||
|     $('#sessionTimeoutModal').modal('show'); | ||||
| } | ||||
|  | ||||
| $(document).on("click", "#js-session-expired-login", function(e) { | ||||
|     const loginModal = $('#modal-admin-login'); | ||||
|     const redirectUrl = window.location.pathname; | ||||
|     window.location.href = `/login?action=${encodeURIComponent(redirectUrl)}`; | ||||
| }); | ||||
|  | ||||
| // show modal login on page load | ||||
| $(document).ready(function () { | ||||
|     const params = new URLSearchParams(window.location.search); | ||||
|     const redirectUrl = $('#redirect-url').val() || params.get('action') || '/'; | ||||
|     $('#modal-admin-login').modal('show'); | ||||
|     $('#redirect-url').val(redirectUrl); | ||||
|     $('#username').focus(); | ||||
|     $('#username').addClass("focusedInput"); | ||||
| }); | ||||
|  | ||||
| // DHCP or Static IP option group | ||||
| $('#chkstatic').on('change', function() { | ||||
|     if (this.checked) { | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| <?php | ||||
|  | ||||
| define('RASPI_BRAND_TEXT', 'RaspAP'); | ||||
| define('RASPI_BRAND_TITLE', RASPI_BRAND_TEXT.' Admin Panel'); | ||||
| define('RASPI_CONFIG', '/etc/raspap'); | ||||
| define('RASPI_CONFIG_NETWORK', RASPI_CONFIG.'/networking/defaults.json'); | ||||
| define('RASPI_CONFIG_PROVIDERS', 'config/vpn-providers.json'); | ||||
| @@ -11,6 +12,7 @@ define('RASPI_CACHE_PATH', sys_get_temp_dir() . '/raspap'); | ||||
| define('RASPI_ERROR_LOG', sys_get_temp_dir() . '/raspap_error.log'); | ||||
| define('RASPI_DEBUG_LOG', 'raspap_debug.log'); | ||||
| define('RASPI_LOG_SIZE_LIMIT', 64); | ||||
| define('RASPI_SESSION_TIMEOUT', 1440); | ||||
|  | ||||
| // Constants for configuration file paths. | ||||
| // These are typical for default RPi installs. Modify if needed. | ||||
|   | ||||
| @@ -1,16 +1,10 @@ | ||||
| <?php | ||||
|  | ||||
| if (RASPI_AUTH_ENABLED) { | ||||
|     $user = $_SERVER['PHP_AUTH_USER'] ?? ''; | ||||
|     $pass = $_SERVER['PHP_AUTH_PW'] ?? ''; | ||||
|  | ||||
|     $auth = new \RaspAP\Auth\HTTPAuth; | ||||
|  | ||||
|     if (!$auth->isLogged()) { | ||||
|         if ($auth->login($user, $pass)) { | ||||
|             $config = $auth->getAuthConfig(); | ||||
|         } else { | ||||
|             $auth->authenticate(); | ||||
|         } | ||||
|         $auth->authenticate(); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| <?php | ||||
|  | ||||
| require_once 'functions.php'; | ||||
| require_once 'session.php'; | ||||
|  | ||||
| if (csrfValidateRequest() && !CSRFValidate()) { | ||||
|     handleInvalidCSRFToken(); | ||||
|   | ||||
| @@ -6,6 +6,7 @@ if (!defined('RASPI_CONFIG')) { | ||||
|  | ||||
| $defaults = [ | ||||
|   'RASPI_BRAND_TEXT' => 'RaspAP', | ||||
|   'RASPI_BRAND_TITLE' => RASPI_BRAND_TEXT.' Admin Panel', | ||||
|   'RASPI_VERSION' => '3.2.4', | ||||
|   'RASPI_CONFIG_NETWORK' => RASPI_CONFIG.'/networking/defaults.json', | ||||
|   'RASPI_CONFIG_PROVIDERS' => 'config/vpn-providers.json', | ||||
| @@ -16,6 +17,7 @@ $defaults = [ | ||||
|   'RASPI_ERROR_LOG' => sys_get_temp_dir() . '/raspap_error.log', | ||||
|   'RASPI_DEBUG_LOG' => 'raspap_debug.log', | ||||
|   'RASPI_LOG_SIZE_LIMIT' =>  64, | ||||
|   'RASPI_SESSION_TIMEOUT' => 1440, | ||||
|  | ||||
|   // Constants for configuration file paths. | ||||
|   // These are typical for default RPi installs. Modify if needed. | ||||
|   | ||||
							
								
								
									
										20
									
								
								includes/footer.php
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										20
									
								
								includes/footer.php
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @@ -1,4 +1,6 @@ | ||||
|  <div class="d-flex align-items-center justify-content-between small"> | ||||
| <?php $_SESSION['lastActivity'] = time(); ?> | ||||
|  | ||||
| <div class="d-flex align-items-center justify-content-between small"> | ||||
|   <div class="text-muted"> | ||||
|     <span class="pe-2"><a href="/about">v<?php echo RASPI_VERSION; ?></a></span>  | | ||||
|     <span class="ps-2">Created by the <a href="https://github.com/RaspAP" target="_blank" rel="noopener">RaspAP Team</a></span> | ||||
| @@ -8,3 +10,19 @@ | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| <div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="sessionTimeoutModal" tabindex="-1" aria-labelledby="sessionTimeoutLabel" aria-hidden="true"> | ||||
|   <div class="modal-dialog modal-dialog-centered"> | ||||
|     <div class="modal-content"> | ||||
|       <div class="modal-header"> | ||||
|         <div class="modal-title" id="sessionTimeoutLabel"><i class="fa fa-clock me-2"></i><?php echo _("Session Expired"); ?></div> | ||||
|       </div> | ||||
|       <div class="modal-body"> | ||||
|         <?php echo _("Your session has expired. Please login to continue.") ?> | ||||
|       </div> | ||||
|       <div class="modal-footer"> | ||||
|         <button type="button" id="js-session-expired-login" class="btn btn-outline btn-primary"><?php echo _("Login"); ?></button> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| <?php require_once 'session.php'; ?> | ||||
| <?php | ||||
| /* Functions for Networking */ | ||||
|  | ||||
| @@ -336,23 +337,26 @@ function CSRFMetaTag() | ||||
|  */ | ||||
| function CSRFValidate() | ||||
| { | ||||
|     if(isset($_POST['csrf_token'])) { | ||||
|         $post_token   = $_POST['csrf_token']; | ||||
|         $header_token = $_SERVER['HTTP_X_CSRF_TOKEN'] ?? null; | ||||
|     if (empty($_SESSION['csrf_token']) || !is_string($_SESSION['csrf_token'])) { | ||||
|         error_log('Session expired or CSRF token is missing.'); | ||||
|         header('Location: /login'); | ||||
|         exit; | ||||
|     } | ||||
|  | ||||
|         if (empty($post_token) && is_null($header_token)) { | ||||
|             return false; | ||||
|         } | ||||
|         $request_token = $post_token; | ||||
|         if (empty($post_token)) { | ||||
|             $request_token = $header_token; | ||||
|         } | ||||
|         if (hash_equals($_SESSION['csrf_token'], $request_token)) { | ||||
|             return true; | ||||
|         } else { | ||||
|             error_log('CSRF violation'); | ||||
|             return false; | ||||
|         } | ||||
|     $post_token = $_POST['csrf_token'] ?? null; | ||||
|     $header_token = $_SERVER['HTTP_X_CSRF_TOKEN'] ?? null; | ||||
|  | ||||
|     if (empty($post_token) && is_null($header_token)) { | ||||
|         error_log('CSRF token missing in the request'); | ||||
|         return false; | ||||
|     } | ||||
|     $request_token = $post_token ?: $header_token; | ||||
|  | ||||
|     if (hash_equals($_SESSION['csrf_token'], $request_token)) { | ||||
|         return true; | ||||
|     } else { | ||||
|         error_log('CSRF token mismatch'); | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										40
									
								
								includes/login.php
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										40
									
								
								includes/login.php
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| <?php | ||||
|  | ||||
| require_once 'includes/config.php'; | ||||
| require_once 'includes/functions.php'; | ||||
|  | ||||
| /** | ||||
|  * Handler for administrative user login | ||||
|  */ | ||||
| function DisplayLogin() | ||||
| { | ||||
|     // initialize auth object | ||||
|     $auth = new \RaspAP\Auth\HTTPAuth; | ||||
|     $status = null; | ||||
|     $redirectUrl = null; | ||||
|  | ||||
|     // handle page action | ||||
|     if (RASPI_AUTH_ENABLED) { | ||||
|         if (isset($_POST['login-auth'])) { | ||||
|             // authenticate user | ||||
|             $username = $_POST['username']; | ||||
|             $password = $_POST['password']; | ||||
|             $redirectUrl = $_POST['redirect-url']; | ||||
|             if ($auth->login($username, $password)) { | ||||
|                 $config = $auth->getAuthConfig(); | ||||
|                 header('Location: ' . $redirectUrl); | ||||
|                 die(); | ||||
|             } else { | ||||
|                 $status = "Login failed"; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     echo renderTemplate( | ||||
|         "login", compact( | ||||
|             "status", | ||||
|             "redirectUrl" | ||||
|         ) | ||||
|     ); | ||||
| } | ||||
|  | ||||
| @@ -70,6 +70,9 @@ function handleCorePageAction(string $page, array &$extraFooterScripts): void | ||||
|         case "/about": | ||||
|             DisplayAbout(); | ||||
|             break; | ||||
|         case "/login": | ||||
|             DisplayLogin(); | ||||
|             break; | ||||
|         default: | ||||
|             DisplayDashboard($extraFooterScripts); | ||||
|     } | ||||
|   | ||||
							
								
								
									
										0
									
								
								includes/restapi.php
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								includes/restapi.php
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @@ -3,3 +3,8 @@ | ||||
| if (session_status() == PHP_SESSION_NONE) { | ||||
|     session_start(); | ||||
| } | ||||
|  | ||||
| if (!isset($_SESSION['lastActivity'])) { | ||||
|     $_SESSION['lastActivity'] = time(); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -23,6 +23,7 @@ | ||||
|  * as you leave these references intact in the header comments of your source files. | ||||
|  */ | ||||
|  | ||||
| require 'includes/session.php'; | ||||
| require 'includes/csrf.php'; | ||||
| ensureCSRFSessionToken(); | ||||
|  | ||||
| @@ -35,6 +36,7 @@ require_once 'includes/functions.php'; | ||||
|  | ||||
| // Default page actions | ||||
| require_once 'includes/dashboard.php'; | ||||
| require_once 'includes/login.php'; | ||||
| require_once 'includes/authenticate.php'; | ||||
| require_once 'includes/admin.php'; | ||||
| require_once 'includes/dhcp.php'; | ||||
| @@ -63,7 +65,7 @@ initializeApp(); | ||||
|     <meta name="description" content=""> | ||||
|     <meta name="author" content=""> | ||||
|  | ||||
|     <title><?php echo _("RaspAP WiFi Configuration Portal"); ?></title> | ||||
|     <title><?php echo RASPI_BRAND_TITLE; ?></title> | ||||
|  | ||||
|     <!-- Bootstrap Core CSS --> | ||||
|     <link href="dist/bootstrap/css/bootstrap.min.css" rel="stylesheet"> | ||||
| @@ -96,6 +98,7 @@ initializeApp(); | ||||
|  | ||||
|   <body class="sb-nav-fixed"> | ||||
|     <!-- Navbar --> | ||||
|     <?php ob_start(); ?> | ||||
|     <?php require_once 'includes/navbar.php'; ?> | ||||
|     <!-- End of Navbar --> | ||||
|     <div id="layoutSidenav"> | ||||
| @@ -123,6 +126,7 @@ initializeApp(); | ||||
|         </footer> | ||||
|       </div> | ||||
|     </div> | ||||
|     <?php ob_end_flush(); ?> | ||||
|     <!-- jQuery --> | ||||
|     <script src="dist/jquery/jquery.min.js"></script> | ||||
|  | ||||
|   | ||||
										
											Binary file not shown.
										
									
								
							| @@ -1566,3 +1566,23 @@ msgstr "Restarting restapi.service" | ||||
| msgid "Information provided by restapi.service" | ||||
| msgstr "Information provided by restapi.service" | ||||
|  | ||||
| #: includes/login.php | ||||
|  | ||||
| msgid "Session Expired" | ||||
| msgstr "Session Expired" | ||||
|  | ||||
| msgid "Your session has expired. Please login to continue." | ||||
| msgstr "Your session has expired. Please login to continue." | ||||
|  | ||||
| msgid "Login" | ||||
| msgstr "Login" | ||||
|  | ||||
| msgid "Administrator login" | ||||
| msgstr "Administrator login" | ||||
|  | ||||
| msgid "Forgot password" | ||||
| msgstr "Forgot password" | ||||
|  | ||||
| msgid "Login failed" | ||||
| msgstr "Login failed" | ||||
|  | ||||
|   | ||||
| @@ -15,12 +15,6 @@ namespace RaspAP\Auth; | ||||
|  | ||||
| class HTTPAuth | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @var string $realm | ||||
|      */ | ||||
|     public $realm = 'Authentication Required'; | ||||
|  | ||||
|     /** | ||||
|      * Stored login credentials | ||||
|      * @var array $auth_config | ||||
| @@ -57,15 +51,11 @@ class HTTPAuth | ||||
|     public function authenticate() | ||||
|     { | ||||
|         if (!$this->isLogged()) { | ||||
|             header('HTTP/1.0 401 Unauthorized'); | ||||
|             header('WWW-Authenticate: Basic realm="'.$this->realm.'"'); | ||||
|             if (function_exists('http_response_code')) { | ||||
|                 // http_response_code will respond with proper HTTP version | ||||
|                 http_response_code(401); | ||||
|             } else { | ||||
|                 header('HTTP/1.0 401 Unauthorized'); | ||||
|             $redirectUrl = $_SERVER['REQUEST_URI']; | ||||
|             if (strpos($redirectUrl, '/login') === false) { | ||||
|                 header('Location: /login?action=' . urlencode($redirectUrl)); | ||||
|                 exit(); | ||||
|             } | ||||
|             exit('Not authorized'.PHP_EOL); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
							
								
								
									
										42
									
								
								templates/login.php
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										42
									
								
								templates/login.php
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,42 @@ | ||||
|  | ||||
| <!-- fullscreen modal --> | ||||
| <div class="modal" id="modal-admin-login" data-bs-backdrop="static" data-bs-keyboard="false" role="dialog" aria-labelledby="ModalLabel" aria-hidden="true"> | ||||
|   <div class="modal-dialog modal-fullscreen" role="document"> | ||||
|     <div class="modal-content"> | ||||
|       <div class="modal-body"> | ||||
|         <div class="row h-100 justify-content-center align-items-center"> | ||||
|           <div class="col-12"> | ||||
|             <!-- branding --> | ||||
|             <div class="text-center mb-3"> | ||||
|               <img src="app/img/raspAP-logo.php" class="navbar-logo" alt="RaspAP logo" class="img-fluid" style="max-width: 100px;"> | ||||
|               <h2 class="login-brand"><?php echo htmlspecialchars(RASPI_BRAND_TEXT); ?></h2> | ||||
|               <div class="mt-2 admin-login"><?php echo _("Administrator login") ?></div> | ||||
|               <div class="text-center text-danger mt-1 mb-3"><?php echo $status ?></div> | ||||
|             </div> | ||||
|             <div class="text-center mb-4"> | ||||
|               <form id="admin-login-form" action="login" method="POST" class="needs-validation" novalidate> | ||||
|               <?php echo CSRFTokenFieldTag() ?> | ||||
|                 <div class="form-group"> | ||||
|                   <input type="hidden" name="login-auth"> | ||||
|                   <input type="hidden" id="redirect-url" name="redirect-url" value="<?php echo htmlspecialchars($redirectUrl, ENT_QUOTES, 'UTF-8'); ?>"> | ||||
|                   <input type="text" class="form-control" id="username" name="username" placeholder="<?php echo _("Username") ?>" required> | ||||
|                 </div> | ||||
|                 <div class="mt-2"> | ||||
|                   <div class="input-group has-validation"> | ||||
|                     <input type="password" class="form-control rounded-start border-end-0 no-right-radius" id="password" name="password" placeholder="<?php echo _("Password") ?>" required> | ||||
|                     <button class="btn bg-white btn-passwd-append border-start-0 js-toggle-password" type="button" id="passwd-toggle" data-bs-target="[name=password]" data-toggle-with="fas fa-eye-slash text-secondary text-opacity-50"> | ||||
|                       <i class="fas fa-eye text-secondary text-opacity-50"></i> | ||||
|                     </button> | ||||
|                   </div> | ||||
|  | ||||
|                 </div> | ||||
|                 <button type="submit" class="btn btn-outline btn-admin-login rounded-pill w-75 mt-4"><?php echo _("Login") ?></button> | ||||
|                 <div class="small mt-2"><a href="https://docs.raspap.com/authentication/#restoring-defaults" target="_blank"><?php echo _("Forgot password") ?></a></div> | ||||
|               </form> | ||||
|             </div> | ||||
|           </div><!-- /.col --> | ||||
|         </div><!-- /.row --> | ||||
|       </div><!-- /.modal-body --> | ||||
|     </div><!-- /.modal-content --> | ||||
|   </div><!-- /.modal-dialog --> | ||||
| </div> | ||||
							
								
								
									
										0
									
								
								templates/restapi.php
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								templates/restapi.php
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
		Reference in New Issue
	
	Block a user