mirror of
https://github.com/billz/raspap-webgui.git
synced 2025-03-01 10:31:47 +00:00
Merge branch 'master' into feat/plugin-manager
This commit is contained in:
commit
a619e7a25b
@ -1,8 +1,8 @@
|
||||

|
||||
[](https://github.com/raspap/raspap-webgui/releases) [](https://github.com/thibmaek/awesome-raspberry-pi) [](https://github.com/sponsors/RaspAP) [](https://app.travis-ci.com/RaspAP/raspap-webgui) [](https://crowdin.com/project/raspap) [](https://twitter.com/rasp_ap) [](https://reddit.com/r/RaspAP) [](https://discord.gg/KVAsaAR)
|
||||
[](https://github.com/raspap/raspap-webgui/releases) [](https://github.com/thibmaek/awesome-raspberry-pi) [](https://github.com/sponsors/RaspAP) [](https://app.travis-ci.com/RaspAP/raspap-webgui) [](https://crowdin.com/project/raspap) [](https://twitter.com/rasp_ap) [](https://reddit.com/r/RaspAP) [](https://discord.gg/KVAsaAR)
|
||||
|
||||
|
||||
RaspAP is feature-rich wireless router software that _just works_ on many popular [Debian-based devices](#supported-operating-systems), including the Raspberry Pi. Our popular [Quick installer](#quick-installer) and [Docker container](#docker-support) create a known-good default configuration for all current Raspberry Pis with onboard wireless. A fully responsive, mobile-ready interface gives you control over the relevant services and networking options. Advanced DHCP settings, WireGuard and OpenVPN support, [SSL certificates](https://docs.raspap.com/ssl-quick/), security audits, [captive portal integration](https://docs.raspap.com/captive/), themes and [multilingual options](https://docs.raspap.com/translations/) are included.
|
||||
RaspAP is feature-rich wireless router software that _just works_ on many popular [Debian-based devices](#supported-operating-systems), including the Raspberry Pi. Our popular [Quick installer](#quick-installer) and [Docker container](#docker-support) create a known-good default configuration for all current Raspberry Pis with onboard wireless. A fully responsive, mobile-ready interface gives you control over the relevant services and networking options. Advanced DHCP settings, WireGuard and OpenVPN support, [SSL certificates](https://docs.raspap.com/ssl/), security audits, [captive portal integration](https://docs.raspap.com/captive/), themes and [multilingual options](https://docs.raspap.com/translations/) are included.
|
||||
|
||||
RaspAP has been featured on sites such as [Instructables](http://www.instructables.com/id/Raspberry-Pi-As-Completely-Wireless-Router/), [Adafruit](https://blog.adafruit.com/2016/06/24/raspap-wifi-configuration-portal-piday-raspberrypi-raspberry_pi/), [Raspberry Pi Weekly](https://www.raspberrypi.org/weekly/commander/) and [Awesome Raspberry Pi](https://project-awesome.org/thibmaek/awesome-raspberry-pi) and implemented in countless projects.
|
||||
|
||||
|
@ -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 {
|
||||
@ -332,6 +333,50 @@ 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;
|
||||
}
|
||||
|
||||
textarea.plugin-log {
|
||||
width: 100%;
|
||||
height: 150px;
|
||||
@ -343,4 +388,3 @@ textarea.plugin-log {
|
||||
font-family: monospace;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
|
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
@ -736,18 +736,18 @@ function clearBlocklistStatus() {
|
||||
$('#cbxblocklist-status').removeClass('check-updated').addClass('check-hidden');
|
||||
}
|
||||
|
||||
// Handler for the wireguard generate key button
|
||||
// Handler for the WireGuard generate key button
|
||||
$('.wg-keygen').click(function(){
|
||||
var entity_pub = $(this).parent('div').prev('input[type="text"]');
|
||||
var entity_priv = $(this).parent('div').next('input[type="hidden"]');
|
||||
var parentGroup = $(this).closest('.input-group');
|
||||
var entity_pub = parentGroup.find('input[type="text"]');
|
||||
var updated = entity_pub.attr('name')+"-pubkey-status";
|
||||
var csrfToken = $('meta[name=csrf_token]').attr('content');
|
||||
var csrfToken = $('meta[name="csrf_token"]').attr('content');
|
||||
$.post('ajax/networking/get_wgkey.php',{'entity':entity_pub.attr('name'), 'csrf_token': csrfToken},function(data){
|
||||
var jsonData = JSON.parse(data);
|
||||
entity_pub.val(jsonData.pubkey);
|
||||
$('#' + updated).removeClass('check-hidden').addClass('check-updated').delay(500).animate({ opacity: 1 }, 700);
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
// Handler for wireguard client.conf download
|
||||
$('.wg-client-dl').click(function(){
|
||||
@ -784,6 +784,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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
<?php
|
||||
|
||||
require_once 'functions.php';
|
||||
require_once 'session.php';
|
||||
|
||||
if (csrfValidateRequest() && !CSRFValidate()) {
|
||||
handleInvalidCSRFToken();
|
||||
|
@ -6,7 +6,8 @@ if (!defined('RASPI_CONFIG')) {
|
||||
|
||||
$defaults = [
|
||||
'RASPI_BRAND_TEXT' => 'RaspAP',
|
||||
'RASPI_VERSION' => '3.2.4',
|
||||
'RASPI_BRAND_TITLE' => RASPI_BRAND_TEXT.' Admin Panel',
|
||||
'RASPI_VERSION' => '3.2.5',
|
||||
'RASPI_CONFIG_NETWORK' => RASPI_CONFIG.'/networking/defaults.json',
|
||||
'RASPI_CONFIG_PROVIDERS' => 'config/vpn-providers.json',
|
||||
'RASPI_CONFIG_API' => RASPI_CONFIG.'/api',
|
||||
@ -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.
|
||||
|
@ -268,6 +268,9 @@ function updateDnsmasqConfig($iface,$status)
|
||||
}
|
||||
$config .= PHP_EOL;
|
||||
}
|
||||
if ($_POST['dhcp-ignore'] == "1") {
|
||||
$config .= 'dhcp-ignore=tag:!known'.PHP_EOL;
|
||||
}
|
||||
file_put_contents("/tmp/dnsmasqdata", $config);
|
||||
$msg = file_exists(RASPI_DNSMASQ_PREFIX.$iface.'.conf') ? 'updated' : 'added';
|
||||
system('sudo cp /tmp/dnsmasqdata '.RASPI_DNSMASQ_PREFIX.$iface.'.conf', $result);
|
||||
|
@ -1,3 +1,5 @@
|
||||
<?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> |
|
||||
@ -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,25 +337,28 @@ function CSRFMetaTag()
|
||||
*/
|
||||
function CSRFValidate()
|
||||
{
|
||||
if(isset($_POST['csrf_token'])) {
|
||||
$post_token = $_POST['csrf_token'];
|
||||
if (empty($_SESSION['csrf_token']) || !is_string($_SESSION['csrf_token'])) {
|
||||
error_log('Session expired or CSRF token is missing.');
|
||||
header('Location: /login');
|
||||
exit;
|
||||
}
|
||||
|
||||
$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;
|
||||
if (empty($post_token)) {
|
||||
$request_token = $header_token;
|
||||
}
|
||||
$request_token = $post_token ?: $header_token;
|
||||
|
||||
if (hash_equals($_SESSION['csrf_token'], $request_token)) {
|
||||
return true;
|
||||
} else {
|
||||
error_log('CSRF violation');
|
||||
error_log('CSRF token mismatch');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the request be CSRF-validated?
|
||||
|
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);
|
||||
}
|
||||
|
@ -3,3 +3,8 @@
|
||||
if (session_status() == PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
if (!isset($_SESSION['lastActivity'])) {
|
||||
$_SESSION['lastActivity'] = time();
|
||||
}
|
||||
|
||||
|
@ -207,7 +207,10 @@ function SaveWireGuardConfig($status)
|
||||
}
|
||||
if (isset($_POST['wg_pendpoint']) && strlen(trim($_POST['wg_pendpoint']) >0 )) {
|
||||
$wg_pendpoint_seg = substr($_POST['wg_pendpoint'],0,strpos($_POST['wg_pendpoint'],':'));
|
||||
if (!filter_var($wg_pendpoint_seg,FILTER_VALIDATE_IP)) {
|
||||
$host_port = explode(':', $wg_pendpoint_seg);
|
||||
$hostname = $host_port[0];
|
||||
if (!filter_var($hostname, FILTER_VALIDATE_IP) &&
|
||||
!filter_var($hostname, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)) {
|
||||
$status->addMessage('Invalid value for endpoint address', 'danger');
|
||||
$good_input = false;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
* @author Lawrence Yau <sirlagz@gmail.com>
|
||||
* @author Bill Zimmerman <billzimmerman@gmail.com>
|
||||
* @license GNU General Public License, version 3 (GPL-3.0)
|
||||
* @version 3.2.4
|
||||
* @version 3.2.5
|
||||
* @link https://github.com/RaspAP/raspap-webgui/
|
||||
* @link https://raspap.com/
|
||||
* @see http://sirlagz.net/2013/02/08/raspap-webgui/
|
||||
@ -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>
|
||||
|
||||
|
@ -1641,3 +1641,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,14 +30,12 @@
|
||||
<option disabled="disabled"></option>
|
||||
<?php echo optionsForSelect(blocklistProviders()) ?>
|
||||
</select>
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-sm btn-outline-secondary rounded-end" type="button" onclick="updateBlocklist()"><?php echo _("Update now"); ?></button>
|
||||
<span id="cbxblocklist-status" class="input-group-addon check-hidden ms-2 mt-1"><i class="fas fa-check"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- /.row -->
|
||||
</div><!-- /.tab-pane | advanded tab -->
|
||||
|
||||
|
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
@ -21,12 +21,10 @@
|
||||
</div>
|
||||
<div class="input-group col-md-12">
|
||||
<input type="text" class="form-control" name="wg-peer" id="wg-peerpubkey" value="<?php echo htmlspecialchars($wg_peerpubkey, ENT_QUOTES); ?>" />
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-outline-secondary rounded-end wg-keygen" type="button"><i class="fas fa-magic"></i></button>
|
||||
<div class="btn btn-outline-secondary rounded-end wg-keygen"><i class="fa-solid fa-wand-magic-sparkles"></i></div>
|
||||
<span id="wg-peer-pubkey-status" class="input-group-addon check-hidden ms-2 mt-1"><i class="fas fa-check"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="mb-3 col-xs-3 col-sm-3 mt-3">
|
||||
|
Loading…
x
Reference in New Issue
Block a user