diff --git a/app/css/all.css b/app/css/all.css index 023eb15b..6553afa5 100644 --- a/app/css/all.css +++ b/app/css/all.css @@ -16,6 +16,10 @@ License: GNU General Public License v3.0 h4.mt-3 { margin-left: 0.5rem; } } +.sidebar.toggled .nav-item .nav-link { + padding: 0.65rem 1rem; +} + .sidebar-brand-text { text-transform: none; color: #212529; @@ -52,7 +56,11 @@ License: GNU General Public License v3.0 .info-item-xs { font-size: 0.7rem; - margin-left: 0.3rem; + margin-left: 0.75rem; +} + +.sb-status { + margin-left: 0.75rem!important; } .info-item-wifi { @@ -235,3 +243,22 @@ button > i.fas { font-size: 1.3rem; } +.was-validated .form-control:valid, +.was-validated .form-control:invalid { + background-position: center right calc(.375em + .4875rem); +} + +.was-validated .form-control:invalid { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e"); + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} + +.was-validated .form-control:valid { + background-size: calc(0.6em + 0.375rem) calc(0.6em + 0.375rem); +} + +.input-group>.input-group-append:not(:last-child)>.btn { + border-top-right-radius: 0.35rem; + border-bottom-right-radius: 0.35rem; +} + diff --git a/app/css/material-dark.php b/app/css/material-dark.php index 524d5e4d..e14ccea0 100644 --- a/app/css/material-dark.php +++ b/app/css/material-dark.php @@ -627,3 +627,18 @@ a.scroll-to-top.rounded i.fas.fa-angle-up { padding: 5px; box-sizing: border-box; } + +.was-validated .form-control:valid, +.was-validated .form-control:invalid { + background-position: center right calc(.375em + .4875rem); +} + +.was-validated .form-control:invalid { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e"); + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} + +.was-validated .form-control:valid { + background-size: calc(0.6em + 0.375rem) calc(0.6em + 0.375rem); +} + diff --git a/app/css/material-light.php b/app/css/material-light.php index 0a87f825..8ee6804e 100644 --- a/app/css/material-light.php +++ b/app/css/material-light.php @@ -633,3 +633,18 @@ a.scroll-to-top.rounded i.fas.fa-angle-up { padding: 5px; box-sizing: border-box; } + +.was-validated .form-control:valid, +.was-validated .form-control:invalid { + background-position: center right calc(.375em + .4875rem); +} + +.was-validated .form-control:invalid { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e"); + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} + +.was-validated .form-control:valid { + background-size: calc(0.6em + 0.375rem) calc(0.6em + 0.375rem); +} + diff --git a/app/js/custom.js b/app/js/custom.js index 3c2a45f4..6c929c26 100644 --- a/app/js/custom.js +++ b/app/js/custom.js @@ -241,6 +241,7 @@ function loadInterfaceDHCPSelect() { $('#chkstatic').closest('.btn').button('toggle').blur(); $('#chkstatic').blur(); $('#chkfallback').prop('disabled', true); + $('#dhcp-iface').removeAttr('disabled'); } else { $('#chkdhcp').closest('.btn').button('toggle'); $('#chkdhcp').closest('.btn').button('toggle').blur(); @@ -249,6 +250,7 @@ function loadInterfaceDHCPSelect() { } if (jsonData.FallbackEnabled || $('#chkdhcp').is(':checked')) { $('#dhcp-iface').prop('disabled', true); + setDhcpFieldsDisabled(); } }); } @@ -259,6 +261,7 @@ function setDHCPToggles(state) { } if ($('#dhcp-iface').is(':checked') && !state) { $('#dhcp-iface').prop('checked', state); + setDhcpFieldsDisabled(); } $('#chkfallback').prop('disabled', state); $('#dhcp-iface').prop('disabled', !state); @@ -365,7 +368,15 @@ $('#js-sys-reboot, #js-sys-shutdown').on('click', function (e) { }); $(document).ready(function(){ - $("#PanelManual").hide(); + $("#PanelManual").hide(); + $('.ip_address').mask('0ZZ.0ZZ.0ZZ.0ZZ', { + translation: { + 'Z': { + pattern: /[0-9]/, optional: true + } + }, + placeholder: "___.___.___.___" + }); }); $('#wg-upload,#wg-manual').on('click', function (e) { @@ -542,6 +553,77 @@ window.addEventListener('load', function() { }); }, false); +// DHCP or Static IP option group +$('#chkstatic').on('change', function() { + if (this.checked) { + setStaticFieldsEnabled(); + } +}); + +$('#chkdhcp').on('change', function() { + this.checked ? setStaticFieldsDisabled() : null; +}); + + +$('input[name="dhcp-iface"]').change(function() { + if ($('input[name="dhcp-iface"]:checked').val() == '1') { + setDhcpFieldsEnabled(); + } else { + setDhcpFieldsDisabled(); + } +}); + + +function setStaticFieldsEnabled() { + $('#txtipaddress').prop('required', true); + $('#txtsubnetmask').prop('required', true); + $('#txtgateway').prop('required', true); + + $('#txtipaddress').removeAttr('disabled'); + $('#txtsubnetmask').removeAttr('disabled'); + $('#txtgateway').removeAttr('disabled'); +} + +function setStaticFieldsDisabled() { + $('#txtipaddress').prop('disabled', true); + $('#txtsubnetmask').prop('disabled', true); + $('#txtgateway').prop('disabled', true); + + $('#txtipaddress').removeAttr('required'); + $('#txtsubnetmask').removeAttr('required'); + $('#txtgateway').removeAttr('required'); +} + +function setDhcpFieldsEnabled() { + $('#txtrangestart').prop('required', true); + $('#txtrangeend').prop('required', true); + $('#txtrangeleasetime').prop('required', true); + $('#cbxrangeleasetimeunits').prop('required', true); + + $('#txtrangestart').removeAttr('disabled'); + $('#txtrangeend').removeAttr('disabled'); + $('#txtrangeleasetime').removeAttr('disabled'); + $('#cbxrangeleasetimeunits').removeAttr('disabled'); + $('#txtdns1').removeAttr('disabled'); + $('#txtdns2').removeAttr('disabled'); + $('#txtmetric').removeAttr('disabled'); +} + +function setDhcpFieldsDisabled() { + $('#txtrangestart').removeAttr('required'); + $('#txtrangeend').removeAttr('required'); + $('#txtrangeleasetime').removeAttr('required'); + $('#cbxrangeleasetimeunits').removeAttr('required'); + + $('#txtrangestart').prop('disabled', true); + $('#txtrangeend').prop('disabled', true); + $('#txtrangeleasetime').prop('disabled', true); + $('#cbxrangeleasetimeunits').prop('disabled', true); + $('#txtdns1').prop('disabled', true); + $('#txtdns2').prop('disabled', true); + $('#txtmetric').prop('disabled', true); +} + // Static Array method Array.range = (start, end) => Array.from({length: (end - start)}, (v, k) => k + start); diff --git a/dist/jquery-mask/jquery.mask.min.js b/dist/jquery-mask/jquery.mask.min.js new file mode 100644 index 00000000..1f22376e --- /dev/null +++ b/dist/jquery-mask/jquery.mask.min.js @@ -0,0 +1,19 @@ +// jQuery Mask Plugin v1.14.16 +// github.com/igorescobar/jQuery-Mask-Plugin +var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.findInternal=function(a,n,f){a instanceof String&&(a=String(a));for(var p=a.length,k=0;kg?h=10*d:e>=h&&e!==g?c.maskDigitPosMapOld[h]||(e=h,h=h-(k-l)-a,c.maskDigitPosMap[h]&&(h=e)):h>e&&(h=h+(l-k)+f)}return h},behaviour:function(d){d= +d||window.event;c.invalid=[];var e=b.data("mask-keycode");if(-1===a.inArray(e,l.byPassKeys)){e=c.getMasked();var h=c.getCaret(),g=b.data("mask-previus-value")||"";setTimeout(function(){c.setCaret(c.calculateCaretPosition(g))},a.jMaskGlobals.keyStrokeCompensation);c.val(e);c.setCaret(h);return c.callbacks(d)}},getMasked:function(a,b){var h=[],f=void 0===b?c.val():b+"",g=0,k=d.length,n=0,p=f.length,m=1,r="push",u=-1,w=0;b=[];if(e.reverse){r="unshift";m=-1;var x=0;g=k-1;n=p-1;var A=function(){return-1< +g&&-1addMessage($errors, 'danger'); + foreach ($errors as $error) { + $status->addMessage($error, 'danger'); + } } if ($return == 1) { $status->addMessage('Dnsmasq configuration failed to be updated.', 'danger'); @@ -118,41 +120,42 @@ function saveDHCPConfig($status) /** * Validates DHCP user input from the $_POST object * - * @return string $errors + * @return array $errors */ function validateDHCPInput() { + $errors = []; define('IFNAMSIZ', 16); $iface = $_POST['interface']; if (!preg_match('/^[^\s\/\\0]+$/', $iface) || strlen($iface) >= IFNAMSIZ ) { - $errors .= _('Invalid interface name.').'
'.PHP_EOL; + $errors[] = _('Invalid interface name.'); } if (!filter_var($_POST['StaticIP'], FILTER_VALIDATE_IP) && !empty($_POST['StaticIP'])) { - $errors .= _('Invalid static IP address.').'
'.PHP_EOL; + $errors[] = _('Invalid static IP address.'); } if (!filter_var($_POST['SubnetMask'], FILTER_VALIDATE_IP) && !empty($_POST['SubnetMask'])) { - $errors .= _('Invalid subnet mask.').'
'.PHP_EOL; + $errors[] = _('Invalid subnet mask.'); } if (!filter_var($_POST['DefaultGateway'], FILTER_VALIDATE_IP) && !empty($_POST['DefaultGateway'])) { - $errors .= _('Invalid default gateway.').'
'.PHP_EOL; + $errors[] = _('Invalid default gateway.'); } if (($_POST['dhcp-iface'] == "1")) { if (!filter_var($_POST['RangeStart'], FILTER_VALIDATE_IP) && !empty($_POST['RangeStart'])) { - $errors .= _('Invalid DHCP range start.').'
'.PHP_EOL; + $errors[] = _('Invalid DHCP range start.'); } if (!filter_var($_POST['RangeEnd'], FILTER_VALIDATE_IP) && !empty($_POST['RangeEnd'])) { - $errors .= _('Invalid DHCP range end.').'
'.PHP_EOL; + $errors[] = _('Invalid DHCP range end.'); } if (!ctype_digit($_POST['RangeLeaseTime']) && $_POST['RangeLeaseTimeUnits'] !== 'i') { - $errors .= _('Invalid DHCP lease time, not a number.').'
'.PHP_EOL; + $errors[] = _('Invalid DHCP lease time, not a number.'); } if (!in_array($_POST['RangeLeaseTimeUnits'], array('m', 'h', 'd', 'i'))) { - $errors .= _('Unknown DHCP lease time unit.').'
'.PHP_EOL; + $errors[] = _('Unknown DHCP lease time unit.'); } if ($_POST['Metric'] !== '' && !ctype_digit($_POST['Metric'])) { - $errors .= _('Invalid metric value, not a number.').'
'.PHP_EOL; + $errors[] = _('Invalid metric value, not a number.'); } } return $errors; diff --git a/includes/functions.php b/includes/functions.php index cbc28f96..78d12bae 100755 --- a/includes/functions.php +++ b/includes/functions.php @@ -435,18 +435,25 @@ function GetDistString($input, $string, $offset, $separator) } /** - * - * @param array $arrConfig + * Parses a configuration file + * Options and values are mapped with "=" characters + * Optional $wg flag is used for parsing WireGuard .conf files + * @param array $arrConfig + * @param boolean $wg * @return $config */ -function ParseConfig($arrConfig) +function ParseConfig($arrConfig, $wg = false) { $config = array(); foreach ($arrConfig as $line) { $line = trim($line); if ($line == "" || $line[0] == "#") { - $config[$option] = null; - continue; + if ($wg) { + $config[$option] = null; + continue; + } else { + continue; + } } if (strpos($line, "=") !== false) { diff --git a/includes/sidebar.php b/includes/sidebar.php index 13558354..34545fc0 100755 --- a/includes/sidebar.php +++ b/includes/sidebar.php @@ -10,15 +10,15 @@
-
Status
+
Status
- % + %
- °C + °C
@@ -57,7 +57,7 @@ diff --git a/includes/sysstats.php b/includes/sysstats.php index 2f567a8b..4bc599e6 100755 --- a/includes/sysstats.php +++ b/includes/sysstats.php @@ -46,10 +46,10 @@ if ($cputemp > 70) { // hostapd status $hostapd = $system->hostapdStatus(); if ($hostapd[0] ==1) { - $hostapd_status = "active"; + $hostapd_status = "up"; $hostapd_led = "service-status-up"; } else { - $hostapd_status = "inactive"; + $hostapd_status = "down"; $hostapd_led = "service-status-down"; } diff --git a/includes/wireguard.php b/includes/wireguard.php index ae1bcfc5..8aad76b5 100755 --- a/includes/wireguard.php +++ b/includes/wireguard.php @@ -8,6 +8,7 @@ require_once 'config.php'; function DisplayWireGuardConfig() { $status = new \RaspAP\Messages\StatusMessage; + $parseFlag = true; if (!RASPI_MONITOR_ENABLED) { $optRules = $_POST['wgRules']; $optConf = $_POST['wgCnfOpt']; @@ -37,7 +38,7 @@ function DisplayWireGuardConfig() // fetch server config exec('sudo cat '. RASPI_WIREGUARD_CONFIG, $return); - $conf = ParseConfig($return); + $conf = ParseConfig($return, $parseFlag); $wg_srvpubkey = exec('sudo cat '. RASPI_WIREGUARD_PATH .'wg-server-public.key', $return); $wg_srvport = ($conf['ListenPort'] == '') ? getDefaultNetValue('wireguard','server','ListenPort') : $conf['ListenPort']; $wg_srvipaddress = ($conf['Address'] == '') ? getDefaultNetValue('wireguard','server','Address') : $conf['Address']; @@ -49,7 +50,7 @@ function DisplayWireGuardConfig() // fetch client config exec('sudo cat '. RASPI_WIREGUARD_PATH.'client.conf', $preturn); - $conf = ParseConfig($preturn); + $conf = ParseConfig($preturn, $parseFlag); $wg_pipaddress = ($conf['Address'] == '') ? getDefaultNetValue('wireguard','peer','Address') : $conf['Address']; $wg_plistenport = ($conf['ListenPort'] == '') ? getDefaultNetValue('wireguard','peer','ListenPort') : $conf['ListenPort']; $wg_pendpoint = ($conf['Endpoint'] == '') ? getDefaultNetValue('wireguard','peer','Endpoint') : $conf['Endpoint']; diff --git a/index.php b/index.php index d3e6b92c..bffc643c 100755 --- a/index.php +++ b/index.php @@ -148,6 +148,9 @@ initializeApp(); + + + diff --git a/locale/en_US/LC_MESSAGES/messages.po b/locale/en_US/LC_MESSAGES/messages.po index 6a2fa643..49536797 100644 --- a/locale/en_US/LC_MESSAGES/messages.po +++ b/locale/en_US/LC_MESSAGES/messages.po @@ -37,11 +37,11 @@ msgstr "WiFi client" msgid "Hotspot" msgstr "Hotspot" -msgid "Memory Use" -msgstr "Memory Use" +msgid "Mem Use" +msgstr "Mem Use" -msgid "CPU Temp" -msgstr "CPU Temp" +msgid "CPU" +msgstr "CPU" msgid "Networking" msgstr "Networking" @@ -98,6 +98,18 @@ msgstr "New password" msgid "Repeat new password" msgstr "Repeat new password" +msgid "Please provide a valid username." +msgstr "Please provide a valid username." + +msgid "Please enter your old password." +msgstr "Please enter your old password." + +msgid "Please enter a new password." +msgstr "Please enter a new password." + +msgid "Please re-enter your new password." +msgstr "Please re-enter your new password." + #: includes/configure_client.php msgid "Client settings" msgstr "Client settings" @@ -473,6 +485,57 @@ msgstr "Disable wpa_supplicant dhcp hook for this interface" msgid "If you manage wireless connections with wpa_supplicant itself, the hook may create unwanted connection events. This option disables the hook." msgstr "If you manage wireless connections with wpa_supplicant itself, the hook may create unwanted connection events. This option disables the hook." +msgid "Please provide a valid IP Address." +msgstr "Please provide a valid IP Address." + +msgid "Please provide a valid Default gateway." +msgstr "Please provide a valid Default gateway." + +msgid "Please provide a valid Default gateway." +msgstr "Please provide a valid Default gateway." + +msgid "Please provide a valid Starting IP Address." +msgstr "Please provide a valid Starting IP Address." + +msgid "Please provide a valid Ending IP Address." +msgstr "Please provide a valid Ending IP Address." + +msgid "Please provide a valid Lease Time." +msgstr "Please provide a valid Lease Time." + +msgid "Invalid interface name." +msgstr "Invalid interface name." + +msgid "Invalid interface name." +msgstr "Invalid interface name." + +msgid "Invalid static IP address." +msgstr "Invalid static IP address." + +msgid "Invalid default gateway." +msgstr "Invalid default gateway." + +msgid "Invalid DHCP range start." +msgstr "Invalid DHCP range start." + +msgid "Invalid DHCP range end." +msgstr "Invalid DHCP range end." + +msgid "Invalid DHCP lease time, not a number." +msgstr "Invalid DHCP lease time, not a number." + +msgid "Unknown DHCP lease time unit." +msgstr "Unknown DHCP lease time unit." + +msgid "Invalid metric value, not a number." +msgstr "Invalid metric value, not a number." + +msgid "DHCP configuration for %s added." +msgstr "DHCP configuration for %s added." + +msgid "DHCP configuration for %s updated." +msgstr "DHCP configuration for %s updated." + #: includes/hostapd.php msgid "Basic" msgstr "Basic" @@ -727,6 +790,12 @@ msgstr "raw output" msgid "Setting wireless regulatory domain to %s" msgstr "Setting wireless regulatory domain to %s" +msgid "Please provide a valid SSID." +msgstr "Please provide a valid SSID." + +msgid "Please provide a valid PSK." +msgstr "Please provide a valid PSK." + #: includes/system.php msgid "System Information" msgstr "System Information" diff --git a/templates/admin.php b/templates/admin.php index ee6543b4..3901556a 100755 --- a/templates/admin.php +++ b/templates/admin.php @@ -11,22 +11,28 @@
showMessages(); ?>

-
+
- + +
+ +
- +
+
+ +
@@ -34,10 +40,13 @@
- +
+
+ +
@@ -45,10 +54,13 @@
- +
+
+ +
diff --git a/templates/dhcp.php b/templates/dhcp.php index 6fe48917..921bbbf0 100755 --- a/templates/dhcp.php +++ b/templates/dhcp.php @@ -29,7 +29,7 @@
showMessages(); ?> - + diff --git a/templates/dhcp/general.php b/templates/dhcp/general.php index 5f257c02..90f1a98d 100644 --- a/templates/dhcp/general.php +++ b/templates/dhcp/general.php @@ -35,23 +35,32 @@
Static IP options
-
+
- + +
+ +
- + +
+ +
- + +
+ +
@@ -98,14 +107,20 @@
- + +
+ +
- + +
+ +
@@ -113,6 +128,9 @@
+
+ +
@@ -122,6 +140,9 @@ +
+ +
diff --git a/templates/dhcp/static_leases.php b/templates/dhcp/static_leases.php index a8d371ba..c1e090c4 100644 --- a/templates/dhcp/static_leases.php +++ b/templates/dhcp/static_leases.php @@ -33,7 +33,7 @@ " class="form-control" autofocus="autofocus">
- " class="form-control"> + " class="form-control ip_address" maxlength="15">
" class="form-control"> diff --git a/templates/hostapd.php b/templates/hostapd.php index ce3dea1a..e888a709 100755 --- a/templates/hostapd.php +++ b/templates/hostapd.php @@ -49,7 +49,7 @@
showMessages(); ?> - + diff --git a/templates/hostapd/basic.php b/templates/hostapd/basic.php index 6fbda270..6ae6170c 100644 --- a/templates/hostapd/basic.php +++ b/templates/hostapd/basic.php @@ -7,9 +7,12 @@
-
+
- + +
+ +
diff --git a/templates/hostapd/security.php b/templates/hostapd/security.php index 7389ee41..3870c26e 100644 --- a/templates/hostapd/security.php +++ b/templates/hostapd/security.php @@ -12,10 +12,13 @@
- +
+
+ +