Merge branch 'master' into feature/zbchristian-clients

This commit is contained in:
Bill Zimmerman 2021-04-15 09:00:48 +02:00 committed by GitHub
commit 0c9152fff3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 289 additions and 134 deletions

View File

@ -7,43 +7,49 @@ assignees: ''
--- ---
**Before submitting an issue** <!-- These comments will NOT appear in your issue, so it's OK to ignore them -->
<!--
Thanks for reporting a bug for RaspAP.
All submitters MUST read this first https://docs.raspap.com/issues/ Before creating a new bug report, all submitters MUST read the issue reporting guidelines:
https://docs.raspap.com/issues/
Have a question or want to suggest a feature? Start or join a discussion https://github.com/raspap/raspap-webgui/discussions Refer to the frequently asked questions (FAQ) and official documentation here:
https://docs.raspap.com/faq/
* [ ] This is a bug report Do you have a question or want to suggest a new feature? Start a Discussion here:
* [ ] I searched existing issues before opening this one https://github.com/RaspAP/raspap-webgui/discussions
* [ ] I checked the FAQ and Wiki before creating this issue
* [ ] I have read and understand the issue reporting guidelines
**Describe the bug** Be sure there are no issues similar to yours that are already open. You can check this by searching the issues in this repository. If there is a duplicate issue, please close this one and add a comment to the existing issue instead.
A clear and concise description of what the bug is. -->
<!-- Provide a general summary of the issue in the Title above -->
**Your environment** ## Checklist
* Raspberry Pi hardware (examples: Pi 3 Model B+, Pi Zero W) <!-- IMPORTANT! Fill in the boxes that apply by marking them like so: [x] -->
* Raspbian version (examples: RPi OS Lite, Armbian) - [ ] This is a bug report
* RaspAP version (reported by the Quick Installer) - [ ] I have searched this repository for existing issues
* Followed the project prerequisites? (Y/N) - [ ] I checked the FAQ and official documentation before creating this issue
* Checked the project FAQ? (Y/N) - [ ] I have read and understand the issue reporting guidelines
* RaspAP Quick Install or Manual setup?
* Using default configuration? (Y/N)
* Simultaneous AP and managed mode? (Y/N)
* Onboard wireless chipset or external adapter?
* Other software or services running with RaspAP?
**Steps to reproduce** ## Bug description
Tell us how to reproduce this issue. Provide as much detailed information as possible. <!-- Provide a detailed description of the issue -->
**Expected behavior** ## Your environment
A clear and concise description of what you expected to happen. 1. Operating System: **ENTER HERE** <!-- RPi OS 32-bit Lite, Armbian, Debian, etc. -->
2. Hardware and version: <!-- RPi Zero/3B+/4, OrangePi 3, etc. -->
3. RaspAP version: <!-- reported by the Quick Installer or About page -->
4. Followed the project prerequisites? <!-- Yes/No -->
5. RaspAP Quick Install or Manual setup? <!-- Quick Install/Manual -->
6. Using default configuration? <!-- Yes/No -->
7. Simultaneous AP and managed mode? <!-- Yes/No -->
8. Onboard wireless chipset or external adapter? <!-- Onboard/External -->
9. Other software or services running with RaspAP?
**Actual behavior** ## Steps to reproduce
Tell us what you observed instead. <!-- Tell us how to reproduce this issue. Provide as much detailed information as possible -->
**Screenshots** ## Screenshots
If applicable, add screenshots to help explain your problem. <!-- If applicable, add screenshots to help explain your problem -->
**Additional context** ## Additional context
Add any other context about the problem here. <!-- Add any other context about the problem here -->

View File

@ -21,7 +21,7 @@ When backers were asked which feature they'd most like to see added to RaspAP, t
✅ OpenVPN service logging ✅ OpenVPN service logging
✅ Night mode toggle ✅ Night mode toggle
✅ Restrict network to static clients ✅ Restrict network to static clients
⚙️ WireGuard support (in progress) ✅ WireGuard support
⚙️ Traffic shaping (in progress) ⚙️ Traffic shaping (in progress)
Look for the list above to grow as we add more exclusive features. Look for the list above to grow as we add more exclusive features.
@ -34,7 +34,7 @@ Below is a list of funding targets. When a funding target is reached, the featur
✅ OpenVPN service logging ✅ OpenVPN service logging
✅ Night mode toggle ✅ Night mode toggle
✅ Restrict network to static clients ✅ Restrict network to static clients
⚙️ WireGuard support (in progress) ✅ WireGuard support
⚙️ Traffic shaping (in progress) ⚙️ Traffic shaping (in progress)
### Frequently asked questions ### Frequently asked questions

1
CNAME
View File

@ -1 +0,0 @@
raspap.com

View File

@ -1,5 +1,5 @@
![](https://i.imgur.com/TCJKWT4.png) ![](https://i.imgur.com/TCJKWT4.png)
[![Release 2.7.2](https://img.shields.io/badge/release-v2.7.2-green)](https://github.com/raspap/raspap-insiders/releases) [![Awesome](https://awesome.re/badge.svg)](https://github.com/thibmaek/awesome-raspberry-pi) [![Financial Contributors on Open Collective](https://opencollective.com/raspap/all/badge.svg?label=financial+contributors)](https://opencollective.com/raspap) ![https://travis-ci.com/github/raspap/raspap-webgui/](https://api.travis-ci.org/RaspAP/raspap-webgui.svg) [![Crowdin](https://badges.crowdin.net/raspap/localized.svg)](https://crowdin.com/project/raspap) [![Twitter URL](https://img.shields.io/twitter/url?label=%40RaspAP&logoColor=%23d8224c&url=https%3A%2F%2Ftwitter.com%2Frasp_ap)](https://twitter.com/rasp_ap) [![Subreddit subscribers](https://img.shields.io/reddit/subreddit-subscribers/RaspAP?style=social)](https://www.reddit.com/r/RaspAP/) [![Release 2.7.2](https://img.shields.io/badge/release-v2.7.2-green)](https://github.com/raspap/raspap-insiders/releases) [![Awesome](https://awesome.re/badge.svg)](https://github.com/thibmaek/awesome-raspberry-pi) [![Insiders Edition](https://img.shields.io/static/v1?label=Insiders%20Edition&message=%E2%9D%A4&logo=GitHub&color=ff69b4)](https://github.com/sponsors/RaspAP) ![https://travis-ci.com/github/raspap/raspap-webgui/](https://api.travis-ci.org/RaspAP/raspap-webgui.svg) [![Crowdin](https://badges.crowdin.net/raspap/localized.svg)](https://crowdin.com/project/raspap) [![Twitter URL](https://img.shields.io/twitter/url?label=%40RaspAP&logoColor=%23d8224c&url=https%3A%2F%2Ftwitter.com%2Frasp_ap)](https://twitter.com/rasp_ap) [![Subreddit subscribers](https://img.shields.io/reddit/subreddit-subscribers/RaspAP?style=social)](https://www.reddit.com/r/RaspAP/)
Welcome to **RaspAP Insiders**. You, the members of the Insiders community, support the sponsorware release model, which means that new features are first exclusively released to sponsors as part of Insiders. Read on for details about how this strategy works—and *thank you* for joining us on this journey. Welcome to **RaspAP Insiders**. You, the members of the Insiders community, support the sponsorware release model, which means that new features are first exclusively released to sponsors as part of Insiders. Read on for details about how this strategy works—and *thank you* for joining us on this journey.
@ -27,11 +27,12 @@ As part of the initial rollout of Insiders, all previous one-time backers of Ras
## Exclusive features ## Exclusive features
The following features are currently available exclusively to sponsors. A tangible side benefit of sponsorship is that Insiders are able to help steer future development of RaspAP. This is done through your Insiders access to discussions, feature requests, issues and pull requests in the private GitHub repository. The following features are currently available exclusively to sponsors. A tangible side benefit of sponsorship is that Insiders are able to help steer future development of RaspAP. This is done through your Insiders access to discussions, feature requests, issues and pull requests in the private GitHub repository.
✅ Manage OpenVPN client configs ✅ [Manage OpenVPN client configs](https://docs.raspap.com/openvpn/#multiple-client-configs)
✅ [OpenVPN certificate authentication](https://docs.raspap.com/openvpn/#certificate-authentication)
✅ OpenVPN service logging ✅ OpenVPN service logging
✅ Night mode toggle ✅ Night mode toggle
✅ Restrict network to static clients ✅ Restrict network to static clients
✅ WireGuard support [WireGuard support](https://docs.raspap.com/wireguard/)
⚙️ Traffic shaping (in progress) ⚙️ Traffic shaping (in progress)
Look for the list above to grow as we add more exlcusive features. Have an idea or suggestion for a future enhancement? Start or join an [Insiders discussion](https://github.com/RaspAP/raspap-insiders/discussions) and let us know! Look for the list above to grow as we add more exlcusive features. Have an idea or suggestion for a future enhancement? Start or join an [Insiders discussion](https://github.com/RaspAP/raspap-insiders/discussions) and let us know!
@ -40,12 +41,7 @@ Look for the list above to grow as we add more exlcusive features. Have an idea
Following is a list of funding targets. When a funding target is reached, the features that are tied to it are merged back into RaspAP and released to the public for general availability. Following is a list of funding targets. When a funding target is reached, the features that are tied to it are merged back into RaspAP and released to the public for general availability.
### $500 ### $500
✅ Manage OpenVPN client configs The first **Insiders Edition** includes the exclusive features listed above.
✅ OpenVPN service logging
✅ Night mode toggle
✅ Restrict network to static clients
✅ WireGuard support
⚙️ Traffic shaping (in progress)
## Frequently asked questions ## Frequently asked questions

View File

@ -45,12 +45,14 @@ if (isset($interface)) {
preg_match('/static\srouters=(.*)/', $matched[0], $static_routers); preg_match('/static\srouters=(.*)/', $matched[0], $static_routers);
preg_match('/static\sdomain_name_server=(.*)/', $matched[0], $static_dns); preg_match('/static\sdomain_name_server=(.*)/', $matched[0], $static_dns);
preg_match('/fallback\sstatic_'.$interface.'/', $matched[0], $fallback); preg_match('/fallback\sstatic_'.$interface.'/', $matched[0], $fallback);
preg_match('/(?:no)?gateway/', $matched[0], $gateway);
$dhcpdata['Metric'] = $metric[1]; $dhcpdata['Metric'] = $metric[1];
$dhcpdata['StaticIP'] = strpos($static_ip[1],'/') ? substr($static_ip[1], 0, strpos($static_ip[1],'/')) : $static_ip[1]; $dhcpdata['StaticIP'] = strpos($static_ip[1],'/') ? substr($static_ip[1], 0, strpos($static_ip[1],'/')) : $static_ip[1];
$dhcpdata['SubnetMask'] = cidr2mask($static_ip[1]); $dhcpdata['SubnetMask'] = cidr2mask($static_ip[1]);
$dhcpdata['StaticRouters'] = $static_routers[1]; $dhcpdata['StaticRouters'] = $static_routers[1];
$dhcpdata['StaticDNS'] = $static_dns[1]; $dhcpdata['StaticDNS'] = $static_dns[1];
$dhcpdata['FallbackEnabled'] = empty($fallback) ? false: true; $dhcpdata['FallbackEnabled'] = empty($fallback) ? false: true;
$dhcpdata['DefaultRoute'] = empty($gateway) || $gateway[0] == "gateway";
echo json_encode($dhcpdata); echo json_encode($dhcpdata);
} }

View File

@ -5,11 +5,11 @@ require_once '../../includes/functions.php';
if (isset($_POST['cfg_id'])) { if (isset($_POST['cfg_id'])) {
$ovpncfg_id = $_POST['cfg_id']; $ovpncfg_id = $_POST['cfg_id'];
$ovpncfg_path = pathinfo(RASPI_OPENVPN_CLIENT_LOGIN, PATHINFO_DIRNAME).'/'; $ovpncfg_path = pathinfo(RASPI_OPENVPN_CLIENT_CONFIG, PATHINFO_DIRNAME).'/';
$ovpncfg_files = $ovpncfg_path .$ovpncfg_id.'_*.conf'; $ovpncfg_files = $ovpncfg_path .$ovpncfg_id.'_*.conf';
// move currently active profile // move currently active profile
$meta = file_get_meta(RASPI_OPENVPN_CLIENT_LOGIN,'#\sfilename\s(.*)'); $meta = file_get_meta(RASPI_OPENVPN_CLIENT_CONFIG,'#\sfilename\s(.*)');
$ovpncfg_client = $ovpncfg_path .$meta.'_client.conf'; $ovpncfg_client = $ovpncfg_path .$meta.'_client.conf';
$ovpncfg_login = $ovpncfg_path .$meta.'_login.conf'; $ovpncfg_login = $ovpncfg_path .$meta.'_login.conf';
exec("sudo mv ".RASPI_OPENVPN_CLIENT_CONFIG." $ovpncfg_client", $return); exec("sudo mv ".RASPI_OPENVPN_CLIENT_CONFIG." $ovpncfg_client", $return);

View File

@ -119,8 +119,14 @@ i.fa.fa-bars:hover{
} }
.info-item { .info-item {
width: 10rem; text-transform: uppercase;
float: left; font-size: 0.7em;
color: #858796;
}
.info-value {
font-size: 0.7rem;
margin-left: 0.7rem;
} }
.info-item-xs { .info-item-xs {

View File

@ -150,8 +150,14 @@ ul.nav-tabs, .nav-tabs .nav-link {
} }
.info-item { .info-item {
width: 10rem; text-transform: uppercase;
float: left; font-size: 0.7em;
color: #858796;
}
.info-value {
font-size: 0.7rem;
margin-left: 0.7rem;
} }
.info-item-xs { .info-item-xs {

View File

@ -249,8 +249,14 @@ hr {
} }
.info-item { .info-item {
width: 12rem; text-transform: uppercase;
float: left; font-size: 0.7em;
color: #858796;
}
.info-value {
font-size: 0.7rem;
margin-left: 0.7rem;
} }
.info-item-xs { .info-item-xs {

View File

@ -205,6 +205,7 @@ function loadInterfaceDHCPSelect() {
$('#txtsubnetmask').val(jsonData.SubnetMask); $('#txtsubnetmask').val(jsonData.SubnetMask);
$('#txtgateway').val(jsonData.StaticRouters); $('#txtgateway').val(jsonData.StaticRouters);
$('#chkfallback')[0].checked = jsonData.FallbackEnabled; $('#chkfallback')[0].checked = jsonData.FallbackEnabled;
$('#default-route').prop('checked', jsonData.DefaultRoute);
$('#txtrangestart').val(jsonData.RangeStart); $('#txtrangestart').val(jsonData.RangeStart);
$('#txtrangeend').val(jsonData.RangeEnd); $('#txtrangeend').val(jsonData.RangeEnd);
$('#txtrangeleasetime').val(jsonData.leaseTime); $('#txtrangeleasetime').val(jsonData.leaseTime);
@ -300,6 +301,17 @@ $('#ovpn-confirm-activate').on('shown.bs.modal', function (e) {
$('.btn-activate', this).data('recordId', data.recordId); $('.btn-activate', this).data('recordId', data.recordId);
}); });
$('#ovpn-userpw,#ovpn-certs').on('click', function (e) {
// e.stopPropagation();
if (this.id == 'ovpn-userpw') {
$('#PanelCerts').hide();
$('#PanelUserPW').show();
} else if (this.id == 'ovpn-certs') {
$('#PanelUserPW').hide();
$('#PanelCerts').show();
}
});
// Add the following code if you want the name of the file appear on select // Add the following code if you want the name of the file appear on select
$(".custom-file-input").on("change", function() { $(".custom-file-input").on("change", function() {
var fileName = $(this).val().split("\\").pop(); var fileName = $(this).val().split("\\").pop();

View File

@ -3,7 +3,7 @@ server.modules += (
) )
$HTTP["url"] =~ "^/REPLACE_ME/(?!(dist|app|ajax|config)).*" { $HTTP["url"] =~ "^/REPLACE_ME/(?!(dist|app|ajax|config)).*" {
url.rewrite-once = ( "^/REPLACE_ME/(.*?)(\?.+)?$"=>"/REPLACE_ME/index.php/$1?$2" ) url.rewrite-once = ( "^/REPLACE_ME/(.*?)(\?.+)?$"=>"/REPLACE_ME/index.php/$1$2" )
server.error-handler-404 = "/REPLACE_ME/index.php" server.error-handler-404 = "/REPLACE_ME/index.php"
} }

View File

@ -247,6 +247,7 @@ function updateDHCPConfig($iface,$status)
$cfg[] = 'profile static_'.$iface; $cfg[] = 'profile static_'.$iface;
$cfg[] = 'fallback static_'.$iface; $cfg[] = 'fallback static_'.$iface;
} }
$cfg[] = $_POST['DefaultRoute'] == '1' ? 'gateway' : 'nogateway';
$dhcp_cfg = file_get_contents(RASPI_DHCPCD_CONFIG); $dhcp_cfg = file_get_contents(RASPI_DHCPCD_CONFIG);
if (!preg_match('/^interface\s'.$iface.'$/m', $dhcp_cfg)) { if (!preg_match('/^interface\s'.$iface.'$/m', $dhcp_cfg)) {
$cfg[] = PHP_EOL; $cfg[] = PHP_EOL;

View File

@ -27,6 +27,8 @@ function DisplayHostAPDConfig()
$arrEncType = array('TKIP' => 'TKIP', 'CCMP' => 'CCMP', 'TKIP CCMP' => 'TKIP+CCMP'); $arrEncType = array('TKIP' => 'TKIP', 'CCMP' => 'CCMP', 'TKIP CCMP' => 'TKIP+CCMP');
$managedModeEnabled = false; $managedModeEnabled = false;
exec("ip -o link show | awk -F': ' '{print $2}'", $interfaces); exec("ip -o link show | awk -F': ' '{print $2}'", $interfaces);
sort($interfaces);
exec("iw reg get | awk '/country / { sub(/:/,\"\",$2); print $2 }'", $country_code); exec("iw reg get | awk '/country / { sub(/:/,\"\",$2); print $2 }'", $country_code);
if (!RASPI_MONITOR_ENABLED) { if (!RASPI_MONITOR_ENABLED) {

View File

@ -53,7 +53,7 @@ function DisplayOpenVPNConfig()
$authUser = current($auth); $authUser = current($auth);
$authPassword = next($auth); $authPassword = next($auth);
} }
$clients = preg_grep('~\login.(conf)$~', scandir(pathinfo(RASPI_OPENVPN_CLIENT_LOGIN, PATHINFO_DIRNAME))); $clients = preg_grep('/client.(conf)$/', scandir(pathinfo(RASPI_OPENVPN_CLIENT_CONFIG, PATHINFO_DIRNAME)));
$logEnable = 0; $logEnable = 0;
if (!empty($_POST) && !isset($_POST['log-openvpn'])) { if (!empty($_POST) && !isset($_POST['log-openvpn'])) {

View File

@ -25,6 +25,7 @@ readonly raspap_wlan0="/etc/dnsmasq.d/090_wlan0.conf"
readonly raspap_adblock="/etc/dnsmasq.d/090_adblock.conf" readonly raspap_adblock="/etc/dnsmasq.d/090_adblock.conf"
readonly raspap_sysctl="/etc/sysctl.d/90_raspap.conf" readonly raspap_sysctl="/etc/sysctl.d/90_raspap.conf"
readonly raspap_network="$raspap_dir/networking/" readonly raspap_network="$raspap_dir/networking/"
readonly raspap_router="/etc/lighttpd/conf-available/50-raspap-router.conf"
readonly rulesv4="/etc/iptables/rules.v4" readonly rulesv4="/etc/iptables/rules.v4"
readonly notracking_url="https://raw.githubusercontent.com/notracking/hosts-blocklists/master/" readonly notracking_url="https://raw.githubusercontent.com/notracking/hosts-blocklists/master/"
webroot_dir="/var/www/html" webroot_dir="/var/www/html"
@ -239,20 +240,25 @@ function _install_lighttpd_configs() {
CONFSRC="$webroot_dir/config/50-raspap-router.conf" CONFSRC="$webroot_dir/config/50-raspap-router.conf"
LTROOT=$(grep "server.document-root" /etc/lighttpd/lighttpd.conf | awk -F '=' '{print $2}' | tr -d " \"") LTROOT=$(grep "server.document-root" /etc/lighttpd/lighttpd.conf | awk -F '=' '{print $2}' | tr -d " \"")
# compare values and get difference # Compare values and get difference
HTROOT=${webroot_dir/$LTROOT} HTROOT=${webroot_dir/$LTROOT}
# remove trailing slash if present # Remove trailing slash if present
HTROOT=$(echo "$HTROOT" | sed -e 's/\/$//') HTROOT=$(echo "$HTROOT" | sed -e 's/\/$//')
# substitute values # Substitute values
awk "{gsub(\"/REPLACE_ME\",\"$HTROOT\")}1" $CONFSRC > /tmp/50-raspap-router.conf awk "{gsub(\"/REPLACE_ME\",\"$HTROOT\")}1" $CONFSRC > /tmp/50-raspap-router.conf
# copy into place # Copy into place
sudo cp /tmp/50-raspap-router.conf /etc/lighttpd/conf-available/ || _install_status 1 "Unable to copy lighttpd config file into place." sudo cp /tmp/50-raspap-router.conf /etc/lighttpd/conf-available/ || _install_status 1 "Unable to copy lighttpd config file into place."
# link into conf-enabled # Link into conf-enabled
echo "Creating link to /etc/lighttpd/conf-enabled" echo "Creating link to /etc/lighttpd/conf-enabled"
if ! [ -L $raspap_router ]; then
echo "Existing 50-raspap-router.conf found. Unlinking."
sudo unlink "/etc/lighttpd/conf-enabled/50-raspap-router.conf"
fi
echo "Linking 50-raspap-router.conf to /etc/lighttpd/conf-enabled/"
sudo ln -s "/etc/lighttpd/conf-available/50-raspap-router.conf" "/etc/lighttpd/conf-enabled/50-raspap-router.conf" || _install_status 1 "Unable to symlink lighttpd config file (this is normal if the link already exists)." sudo ln -s "/etc/lighttpd/conf-available/50-raspap-router.conf" "/etc/lighttpd/conf-enabled/50-raspap-router.conf" || _install_status 1 "Unable to symlink lighttpd config file (this is normal if the link already exists)."
sudo systemctl restart lighttpd.service || _install_status 1 "Unable to restart lighttpd" sudo systemctl restart lighttpd.service || _install_status 1 "Unable to restart lighttpd"
_install_status 0 _install_status 0
@ -363,18 +369,10 @@ function _prompt_install_wireguard() {
# Install Wireguard from the Debian unstable distro # Install Wireguard from the Debian unstable distro
function _install_wireguard() { function _install_wireguard() {
_install_log "Configure WireGuard support" _install_log "Configure WireGuard support"
if [ "$OS" == "Raspbian" ]; then if [ "$OS" == "Debian" ]; then
echo "Installing raspberrypi-kernel-headers" echo 'deb http://ftp.debian.org/debian buster-backports main' | sudo tee /etc/apt/sources.list.d/buster-backports.list || _install_status 1 "Unable to add Debian backports repo"
sudo apt-get install $apt_option raspberrypi-kernel-headers || _install_status 1 "Unable to install raspberrypi-kernel-headers"
fi fi
echo "Installing WireGuard from Debian unstable distro" echo "Installing wireguard from apt"
echo "Adding Debian distro"
echo "deb http://deb.debian.org/debian/ unstable main" | sudo tee --append /etc/apt/sources.list.d/unstable.list || _install_status 1 "Unable to append to sources.list"
sudo apt-get install dirmngr || _install_status 1 "Unable to install dirmngr"
echo "Adding Debian distro keys"
sudo wget -q -O - https://ftp-master.debian.org/keys/archive-key-$(lsb_release -sr).asc | sudo apt-key add - || _install_status 1 "Unable to add keys"
printf 'Package: *\nPin: release a=unstable\nPin-Priority: 150\n' | sudo tee --append /etc/apt/preferences.d/limit-unstable || _install_status 1 "Unable to append to preferences.d"
echo "Installing WireGuard"
sudo apt-get update && sudo apt-get install $apt_option wireguard || _install_status 1 "Unable to install wireguard" sudo apt-get update && sudo apt-get install $apt_option wireguard || _install_status 1 "Unable to install wireguard"
echo "Enabling wg-quick@wg0" echo "Enabling wg-quick@wg0"
sudo systemctl enable wg-quick@wg0 || _install_status 1 "Failed to enable wg-quick service" sudo systemctl enable wg-quick@wg0 || _install_status 1 "Failed to enable wg-quick service"
@ -659,9 +657,10 @@ function _optimize_php() {
function _install_complete() { function _install_complete() {
_install_log "Installation completed" _install_log "Installation completed"
echo "Join RaspAP Insiders for access to exclusive features:" echo "Join RaspAP Insiders for early access to exclusive features!"
echo -e "${ANSI_RASPBERRY}" echo -e "${ANSI_RASPBERRY}"
echo "> https://github.com/sponsors/RaspAP" echo "> https://docs.raspap.com/insiders/"
echo "> https://github.com/sponsors/RaspAP/"
echo -e "${ANSI_RESET}" echo -e "${ANSI_RESET}"
if [ "$assume_yes" == 0 ]; then if [ "$assume_yes" == 0 ]; then
# Prompt to reboot if wired ethernet (eth0) is connected. # Prompt to reboot if wired ethernet (eth0) is connected.

View File

@ -187,7 +187,8 @@ function _display_welcome() {
function _get_release() { function _get_release() {
readonly RASPAP_LATEST=$(curl -s "https://api.github.com/repos/$repo/releases/latest" | grep -Po '"tag_name": "\K.*?(?=")' ) readonly RASPAP_LATEST=$(curl -s "https://api.github.com/repos/$repo/releases/latest" | grep -Po '"tag_name": "\K.*?(?=")' )
if [ "$insiders" == 1 ]; then if [ "$insiders" == 1 ]; then
readonly RASPAP_INSIDERS_LATEST=$(curl -s "https://install.raspap.com/repos/RaspAP/raspap-insiders/releases/latest/" | grep -Po '"tag_name": "\K.*?(?=")' ) repo="RaspAP/raspap-insiders"
readonly RASPAP_INSIDERS_LATEST=$(curl -s "https://api.raspap.com/repos/RaspAP/raspap-insiders/releases/latest/" | grep -Po '"tag_name": "\K.*?(?=")' )
readonly RASPAP_RELEASE="${RASPAP_INSIDERS_LATEST} Insiders" readonly RASPAP_RELEASE="${RASPAP_INSIDERS_LATEST} Insiders"
else else
readonly RASPAP_RELEASE="${RASPAP_LATEST}" readonly RASPAP_RELEASE="${RASPAP_LATEST}"

Binary file not shown.

View File

@ -380,6 +380,9 @@ msgstr "Clients with a particular hardware MAC address can always be allocated t
msgid "This option adds <code>dhcp-host</code> entries to the dnsmasq configuration." msgid "This option adds <code>dhcp-host</code> entries to the dnsmasq configuration."
msgstr "This option adds <code>dhcp-host</code> entries to the dnsmasq configuration." msgstr "This option adds <code>dhcp-host</code> entries to the dnsmasq configuration."
msgid "This toggles the <code>gateway</code>/<code>nogateway</code> option for this interface in the DHCPCD configuration."
msgstr "This toggles the <code>gateway</code>/<code>nogateway</code> option for this interface in the DHCPCD configuration."
#: includes/hostapd.php #: includes/hostapd.php
msgid "Basic" msgid "Basic"
msgstr "Basic" msgstr "Basic"
@ -725,6 +728,36 @@ msgstr "Cancel"
msgid "Enable this option to log <code>openvpn</code> activity." msgid "Enable this option to log <code>openvpn</code> activity."
msgstr "Enable this option to log <code>openvpn</code> activity." msgstr "Enable this option to log <code>openvpn</code> activity."
msgid "Authentification Method"
msgstr "Authentification Method"
msgid "Username and password"
msgstr "Username and password"
msgid "Certificates"
msgstr "Certificates"
msgid "Enter username and password"
msgstr "Enter username and password"
msgid "Certificates in the configuration file"
msgstr "Certificates in the configuration file"
msgid "RaspAP supports certificates by including them in the configuration file."
msgstr "RaspAP supports certificates by including them in the configuration file."
msgid "Signing certification authority (CA) certificate (e.g. <code>ca.crt</code>): enclosed in <code>&lt;ca> ... &lt;/ca></code> tags."
msgstr "Signing certification authority (CA) certificate (e.g. <code>ca.crt</code>): enclosed in <code>&lt;ca> ... &lt;/ca></code> tags."
msgid "Client certificate (public key) (e.g. <code>client.crt</code>): enclosed in <code>&lt;cert> ... &lt;/cert></code> tags."
msgstr "Client certificate (public key) (e.g. <code>client.crt</code>): enclosed in <code>&lt;cert> ... &lt;/cert></code> tags."
msgid "Private key of the client certificate (e.g. <code>client.key</code>): enclosed in <code>&lt;key> ... &lt;/key></code> tags."
msgstr "Private key of the client certificate (e.g. <code>client.key</code>): enclosed in <code>&lt;key> ... &lt;/key></code> tags."
msgid "Configuration File"
msgstr "Configuration File"
#: includes/torproxy.php #: includes/torproxy.php
msgid "TOR is not running" msgid "TOR is not running"
msgstr "TOR is not running" msgstr "TOR is not running"

View File

@ -20,7 +20,7 @@
<div class="col-lg-12"> <div class="col-lg-12">
<div class="card mb-3"> <div class="card mb-3">
<div class="card-body"> <div class="card-body">
<h4><?php echo _("Hourly traffic amount"); ?></h4> <h4 class="card-title"><?php echo _("Hourly traffic amount"); ?></h4>
<div id="divInterface" class="d-none"><?php echo $apInterface; ?></div> <div id="divInterface" class="d-none"><?php echo $apInterface; ?></div>
<div class="col-md-12"> <div class="col-md-12">
<canvas id="divDBChartBandwidthhourly"></canvas> <canvas id="divDBChartBandwidthhourly"></canvas>
@ -32,45 +32,85 @@
<div class="col-sm-6 align-items-stretch"> <div class="col-sm-6 align-items-stretch">
<div class="card h-100"> <div class="card h-100">
<div class="card-body wireless"> <div class="card-body wireless">
<h4><?php echo _("$client_title"); ?></h4> <h4 class="card-title"><?php echo _("$client_title"); ?></h4>
<div class="row justify-content-md-center"> <div class="row ml-1">
<div class="col-md"> <div class="col-sm">
<?php $valEcho=function($cl,$id) {$val = isset($cl[$id])&& !empty($cl[$id]) ? $cl[$id] : "-"; echo htmlspecialchars($val,ENT_QUOTES);} ?> <?php $valEcho=function($cl,$id) {$val = isset($cl[$id])&& !empty($cl[$id]) ? $cl[$id] : "-"; echo htmlspecialchars($val,ENT_QUOTES);} ?>
<?php if ($clientinfo["type"] == "wlan") : // WIRELESS ?> <?php if ($clientinfo["type"] == "wlan") : // WIRELESS ?>
<div class="info-item"><?php echo _("Connected To"); ?></div><div><?php $valEcho($clientinfo,"ssid"); ?></div> <div class="row mb-1">
<div class="info-item"><?php echo _("AP Mac Address"); ?></div><div><?php $valEcho($clientinfo,"ap-mac"); ?></div> <div class="info-item col-xs-3"><?php echo _("Connected To"); ?></div><div class="info-value col-xs-3"><?php $valEcho($clientinfo,"ssid"); ?></div>
<div class="info-item"><?php echo _("Bitrate"); ?></div><div><?php $valEcho($clientinfo,"bitrate"); ?></div> </div>
<div class="info-item"><?php echo _("Signal Level"); ?></div><div><?php $valEcho($clientinfo,"signal"); ?></div> <div class="row mb-1">
<div class="info-item"><?php echo _("Transmit Power"); ?></div><div><?php echo htmlspecialchars($txPower, ENT_QUOTES); ?></div> <div class="info-item col-xs-3"><?php echo _("AP Mac Address"); ?></div><div class="info-value col-xs-3"><?php $valEcho($clientinfo,"ap-mac"); ?></div>
<div class="info-item"><?php echo _("Frequency"); ?></div><div><?php $valEcho($clientinfo,"freq"); ?></div> </div>
<div class="row mb-1">
<div class="info-item col-xs-3"><?php echo _("Bitrate"); ?></div><div class="info-value col-xs-3"><?php $valEcho($clientinfo,"bitrate"); ?></div>
</div>
<div class="row mb-1">
<div class="info-item col-xs-3"><?php echo _("Signal Level"); ?></div><div class="info-value col-xs-3"><?php $valEcho($clientinfo,"signal"); ?></div>
</div>
<div class="row mb-1">
<div class="info-item col-xs-3"><?php echo _("Transmit Power"); ?></div><div class="info-value col-xs-3"><?php echo htmlspecialchars($txPower, ENT_QUOTES); ?></div>
</div>
<div class="row mb-1">
<div class="info-item col-xs-3"><?php echo _("Frequency"); ?></div><div class="info-value col-xs-3"><?php $valEcho($clientinfo,"freq"); ?></div>
</div>
<?php elseif ($clientinfo["type"] == "phone" ) : // Smartphones (tethering over USB) ?> <?php elseif ($clientinfo["type"] == "phone" ) : // Smartphones (tethering over USB) ?>
<div class="info-item"><?php echo _("Device"); ?></div><div><?php $valEcho($clientinfo,"vendor")." ". $valEcho($clientinfo,"model"); ?></div> <div class="row mb-1">
<div class="info-item"><?php echo _("IP Address"); ?></div><div><?php $valEcho($clientinfo,"ipaddress"); ?></div> <div class="info-item col-xs-3"><?php echo _("Device"); ?></div><div class="info-value col-xs-3"><?php $valEcho($clientinfo,"vendor")." ". $valEcho($clientinfo,"model"); ?></div>
</div>
<div class="row mb-1">
<div class="info-item col-xs-3"><?php echo _("IP Address"); ?></div><div class="info-value col-xs-3"><?php $valEcho($clientinfo,"ipaddress"); ?></div>
</div>
<?php elseif ($clientinfo["type"] == "hilink" ) : // MOBILE DATA - ROUTER MODE (HILINK) ?> <?php elseif ($clientinfo["type"] == "hilink" ) : // MOBILE DATA - ROUTER MODE (HILINK) ?>
<?php <?php
exec('ip route list | sed -rn "s/default via (([0-9]{1,3}\.){3}[0-9]{1,3}).*dev '.$clientinfo["name"].'.*/\1/p"',$gw); // get gateway exec('ip route list | sed -rn "s/default via (([0-9]{1,3}\.){3}[0-9]{1,3}).*dev '.$clientinfo["name"].'.*/\1/p"',$gw); // get gateway
$gw=empty($gw) ? "" : $gw[0]; $gw=empty($gw) ? "" : $gw[0];
?> ?>
<div class="info-item"><?php echo _("Device"); ?></div><div><?php $valEcho($clientinfo,"model")." (Hilink)"; ?></div> <div class="row mb-1">
<div class="info-item"><?php echo _("Connection mode"); ?></div><div><?php $valEcho($clientinfo,"mode"); ?></div> <div class="info-item col-xs-3"><?php echo _("Device"); ?></div><div class="info-value col-xs-3"><?php $valEcho($clientinfo,"model")." (Hilink)"; ?></div>
<div class="info-item"><?php echo _("Signal quality"); ?></div><div><?php $valEcho($clientinfo,"signal"); ?></div> </div>
<div class="info-item"><?php echo _("Network"); ?></div><div><?php $valEcho($clientinfo,"operator"); ?></div> <div class="row mb-1">
<div class="info-item"><?php echo _("WAN IP"); ?></div><div><?php $valEcho($clientinfo,"wan_ip"); ?></div> <div class="info-item col-xs-3"><?php echo _("Connection mode"); ?></div><div class="info-value col-xs-3"><?php $valEcho($clientinfo,"mode"); ?></div>
<div class="info-item"><?php echo _("Web-GUI"); ?></div><div><?php if(!empty($gw)) echo '<a href="http://'.$gw.'" >'.$gw."</a>"; ?></div> </div>
<div class="row mb-1">
<div class="info-item col-xs-3"><?php echo _("Signal quality"); ?></div><div class="info-value col-xs-3"><?php $valEcho($clientinfo,"signal"); ?></div>
</div>
<div class="row mb-1">
<div class="info-item col-xs-3"><?php echo _("Network"); ?></div><div class="info-value col-xs-3"><?php $valEcho($clientinfo,"operator"); ?></div>
</div>
<div class="row mb-1">
<div class="info-item col-xs-3"><?php echo _("WAN IP"); ?></div><div class="info-value col-xs-3"><?php $valEcho($clientinfo,"wan_ip"); ?></div>
</div>
<div class="row mb-1">
<div class="info-item col-xs-3"><?php echo _("Web-GUI"); ?></div><div class="info-value col-xs-3"><?php if(!empty($gw)) echo '<a href="http://'.$gw.'" >'.$gw."</a>"; ?></div>
</div>
<?php elseif ($clientinfo["type"] == "ppp" ) : // MOBILE DATA MODEM) ?> <?php elseif ($clientinfo["type"] == "ppp" ) : // MOBILE DATA MODEM) ?>
<div class="info-item"><?php echo _("Device"); ?></div><div><?php $valEcho($clientinfo,"model"); ?></div> <div class="row mb-1">
<div class="info-item"><?php echo _("Connection mode"); ?></div><div><?php $valEcho($clientinfo,"mode"); ?></div> <div class="info-item col-xs-3"><?php echo _("Device"); ?></div><div class="info-value col-xs-3"><?php $valEcho($clientinfo,"model"); ?></div>
<div class="info-item"><?php echo _("Signal strength"); ?></div><div><?php $valEcho($clientinfo,"signal"); ?></div> </div>
<div class="info-item"><?php echo _("Network"); ?></div><div><?php $valEcho($clientinfo,"operator"); ?></div> <div class="row mb-1">
<div class="info-item col-xs-3"><?php echo _("Connection mode"); ?></div><div class="info-value col-xs-3"><?php $valEcho($clientinfo,"mode"); ?></div>
</div>
<div class="row mb-1">
<div class="info-item col-xs-3"><?php echo _("Signal strength"); ?></div><div class="info-value col-xs-3"><?php $valEcho($clientinfo,"signal"); ?></div>
</div>
<div class="row mb-1">
<div class="info-item col-xs-3"><?php echo _("Network"); ?></div><div class="info-value col-xs-3"><?php $valEcho($clientinfo,"operator"); ?></div>
</div>
<?php elseif ($clientinfo["type"] == "eth" ) : // ETHERNET ?> <?php elseif ($clientinfo["type"] == "eth" ) : // ETHERNET ?>
<div class="info-item"><?php echo _("Device"); ?></div><div><?php $valEcho($clientinfo,"vendor")." ".$valEcho($clientinfo,"model"); ?></div> <div class="row mb-1">
<div class="info-item"><?php echo _("IP Address"); ?></div><div><?php echo $valEcho($clientinfo,"ipaddress"); ?></div> <div class="info-item col-xs-3"><?php echo _("Device"); ?></div><div class="info-value col-xs-3"><?php $valEcho($clientinfo,"vendor")." ".$valEcho($clientinfo,"model"); ?></div>
</div>
<div class="row mb-1">
<div class="info-item col-xs-3"><?php echo _("IP Address"); ?></div><div class="info-value col-xs-3"><?php echo $valEcho($clientinfo,"ipaddress"); ?></div>
</div>
<?php else : // NO CLIENT ?> <?php else : // NO CLIENT ?>
<div class=""><?php echo _("No Client device or not yet configured"); ?></div> <div class=""><?php echo _("No Client device or not yet configured"); ?></div>
<?php endif; ?> <?php endif; ?>
</div> </div>
<?php if ($isClientConfigured) : ?> <?php if ($isClientConfigured) : ?>
<div class="col-md mt-2 d-flex justify-content-center"> <div class="col-md d-flex">
<?php <?php
preg_match("/.*\((\s*\d*)\s*%\s*\)/",$clientinfo["signal"],$match); preg_match("/.*\((\s*\d*)\s*%\s*\)/",$clientinfo["signal"],$match);
$strLinkQuality=array_key_exists(1,$match) ? $match[1] : 0; $strLinkQuality=array_key_exists(1,$match) ? $match[1] : 0;
@ -88,7 +128,7 @@
<div class="col-sm-6"> <div class="col-sm-6">
<div class="card h-100 mb-3"> <div class="card h-100 mb-3">
<div class="card-body"> <div class="card-body">
<h4><?php echo _("Connected Devices"); ?></h4> <h4 class="card-title"><?php echo _("Connected Devices"); ?></h4>
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-hover"> <table class="table table-hover">
<thead> <thead>

View File

@ -55,6 +55,18 @@
</div> </div>
</div> </div>
<div class="row">
<div class="form-group col-md-6">
<div class="custom-control custom-switch">
<input class="custom-control-input" id="default-route" type="checkbox" name="DefaultRoute" value="1" aria-describedby="default-route-description">
<label class="custom-control-label" for="default-route"><?php echo _("Install a default route for this interface") ?></label>
</div>
<p class="mb-0" id="default-route-description">
<small><?php echo _("This toggles the <code>gateway</code>/<code>nogateway</code> option for this interface in the DHCPCD configuration.") ?></small>
</p>
</div>
</div>
<h5 class="mt-1">DHCP options</h5> <h5 class="mt-1">DHCP options</h5>
<div class="row"> <div class="row">
<div class="form-group col-md-6"> <div class="form-group col-md-6">

View File

@ -233,7 +233,7 @@
<option value="OM">Oman</option> <option value="OM">Oman</option>
<option value="PK">Pakistan</option> <option value="PK">Pakistan</option>
<option value="PW">Palau</option> <option value="PW">Palau</option>
<option value="PS">Palestinian Territory, Occupied</option> <option value="PS">Palestinian Territory</option>
<option value="PA">Panama</option> <option value="PA">Panama</option>
<option value="PG">Papua New Guinea</option> <option value="PG">Papua New Guinea</option>
<option value="PY">Paraguay</option> <option value="PY">Paraguay</option>
@ -281,7 +281,7 @@
<option value="SE">Sweden</option> <option value="SE">Sweden</option>
<option value="CH">Switzerland</option> <option value="CH">Switzerland</option>
<option value="SY">Syrian Arab Republic</option> <option value="SY">Syrian Arab Republic</option>
<option value="TW">Taiwan, Province of China</option> <option value="TW">Taiwan</option>
<option value="TJ">Tajikistan</option> <option value="TJ">Tajikistan</option>
<option value="TZ">Tanzania, United Republic of</option> <option value="TZ">Tanzania, United Republic of</option>
<option value="TH">Thailand</option> <option value="TH">Thailand</option>

View File

@ -45,8 +45,7 @@
</div><!-- /.tab-content --> </div><!-- /.tab-content -->
<?php echo $buttons ?> <?php echo $buttons ?>
</form> </form>
</div>
</div><!-- /.card-body --> </div><!-- /.card-body -->
<div class="card-footer"><?php echo _("Information provided by openvpn"); ?></div> <div class="card-footer"><?php echo _("Information provided by openvpn"); ?></div>
</div><!-- /.card --> </div><!-- /.card -->

View File

@ -8,11 +8,11 @@
</p> </p>
<div class="openvpn-configs js-openvpn-configs-container"> <div class="openvpn-configs js-openvpn-configs-container">
<?php foreach ($clients as $client) : <?php foreach ($clients as $client) :
if ($client == "login.conf") { if ($client == "client.conf") {
$label = file_get_meta(RASPI_OPENVPN_CLIENT_LOGIN,'#\sfilename\s(.*)'); $label = file_get_meta(RASPI_OPENVPN_CLIENT_CONFIG,'#\sfilename\s(.*)');
$btn_class = "active"; $btn_class = "active";
} else { } else {
$label = trim(pathinfo($client, PATHINFO_FILENAME), "_login"); $label = preg_replace('/_client$/','',pathinfo($client, PATHINFO_FILENAME));
$client = $label; $client = $label;
$btn_class = "disabled"; $btn_class = "disabled";
}?> }?>

View File

@ -1,36 +1,71 @@
<div class="tab-pane active" id="openvpnclient"> <div class="tab-pane active" id="openvpnclient">
<h4 class="mt-3"><?php echo _("Client settings"); ?></h4> <h4 class="mt-3"><?php echo _("Client settings"); ?></h4>
<div class="row"> <div class="row">
<div class="col"> <div class="col-lg-8">
<div class="row"> <div class="row mb-2">
<div class="col-lg-12 mt-2 mb-2"> <div class="col-lg-12 mt-2 mb-2">
<div class="info-item"><?php echo _("IPv4 Address"); ?></div> <div class="row ml-1">
<div class="info-item"><?php echo htmlspecialchars($public_ip, ENT_QUOTES); ?><a class="text-gray-500" href="https://ipapi.co/<?php echo($public_ip); ?>" target="_blank" rel="noopener noreferrer"><i class="fas fa-external-link-alt ml-2"></i></a></div> <div class="info-item col-xs-3"><?php echo _("IPv4 Address"); ?></div>
</div> <div class="info-value col-xs-3"><?php echo htmlspecialchars($public_ip, ENT_QUOTES); ?><a class="text-gray-500" href="https://ipapi.co/<?php echo($public_ip); ?>" target="_blank" rel="noopener noreferrer"><i class="fas fa-external-link-alt ml-2"></i></a></div>
</div>
</div>
</div> </div>
<div class="row"> <h5><?php echo _("Authentification Method"); ?></h5>
<div class="form-group col-lg-12"> <div class="col-sm-12 mt-2 mb-2 form-check">
<label for="code"><?php echo _("Username"); ?></label> <input class="form-check-input" id="ovpn-userpw" name="sel1" value="userpw" data-toggle="" data-parent="#clientsettings" data-target="#UserPW" type="radio" checked>
<input type="text" class="form-control" name="authUser" value="<?php echo htmlspecialchars($authUser, ENT_QUOTES); ?>" /> <label class="form-check-label"><?php echo _("Username and password"); ?></label>
</div>
</div> </div>
<div class="row"> <div class="col-sm-12 mt-2 mb-2 form-check">
<div class="form-group col-lg-12"> <input class="form-check-input" id="ovpn-certs" name="sel1" value="certs" data-toggle="" data-parent="#clientsettings" data-target="#Certs" type="radio">
<label for="code"><?php echo _("Password"); ?></label> <label class="form-check-label"><?php echo _("Certificates"); ?></label>
<input type="password" class="form-control" name="authPassword" value="<?php echo htmlspecialchars($authPassword, ENT_QUOTES); ?>" />
</div>
</div> </div>
<div class="row"> <div class="col-sm-12 ml-2">
<div class="form-group col-lg-12"> <div class="panel-group" id="clientsettings">
<div class="custom-file"> <div class="panel panel-default panel-collapse" id="PanelUserPW" >
<input type="file" class="custom-file-input" name="customFile" id="customFile"> <div class="panel-heading">
<label class="custom-file-label" for="customFile"><?php echo _("Select OpenVPN configuration file (.ovpn)"); ?></label> <h5 class="panel-title"><?php echo _("Enter username and password"); ?></h5>
</div> </div>
</div> <div class="panel-body">
</div> <div class="form-group col-lg-12">
</div><!-- col--> <label for="code"><?php echo _("Username"); ?></label>
<div class="col-sm"> <input type="text" class="form-control" name="authUser" value="<?php echo htmlspecialchars($authUser, ENT_QUOTES); ?>" />
<a href="https://go.nordvpn.net/aff_c?offer_id=15&aff_id=36402&url_id=902"><img src="app/img/no-trace-200x200.png" class="float-left mb-3 mt-3"></a> </div>
<div class="form-group col-lg-12">
<label for="code"><?php echo _("Password"); ?></label>
<input type="password" class="form-control" name="authPassword" value="<?php echo htmlspecialchars($authPassword, ENT_QUOTES); ?>" />
</div>
</div>
</div><!-- panel -->
<div class="panel panel-default panel-collapse collapse in" id="PanelCerts">
<div class="panel-body">
<div class="panel-heading">
<h5 class="panel-title"><?php echo _("Certificates in the configuration file"); ?></h5>
</div>
<p><?php echo _("RaspAP supports certificates by including them in the configuration file."); ?>
<ul>
<small>
<li><?php echo _("Signing certification authority (CA) certificate (e.g. <code>ca.crt</code>): enclosed in <code>&lt;ca> ... &lt;/ca></code> tags."); ?></li>
<li><?php echo _("Client certificate (public key) (e.g. <code>client.crt</code>): enclosed in <code>&lt;cert> ... &lt;/cert></code> tags."); ?></li>
<li><?php echo _("Private key of the client certificate (e.g. <code>client.key</code>): enclosed in <code>&lt;key> ... &lt;/key></code> tags."); ?></li>
</small>
</ul>
</p>
</div>
</div> <!-- panel -->
</div> <!-- panel-group -->
</div> <!-- col -->
<div class="col-sm-12 ">
<div class="form-group">
<h5 class="panel-title"><?php echo _("Configuration File"); ?></h4>
<div class="custom-file">
<input type="file" class="custom-file-input" name="customFile" id="customFile">
<label class="custom-file-label" for="customFile"><?php echo _("Select OpenVPN configuration file (.ovpn)"); ?></label>
</div>
</div>
</div> <!-- col -->
</div><!-- col-8 -->
<div class="col-sm-auto">
<a href="https://go.nordvpn.net/aff_c?offer_id=15&aff_id=36402&url_id=902"><img src="app/img/no-trace-200x200.png" class="float-left mb-3 mt-3"></a>
</div> </div>
</div><!-- /.row --> </div><!-- /.row -->
</div><!-- /.tab-pane | general tab --> </div><!-- /.tab-pane | general tab -->

View File

@ -4712,9 +4712,9 @@ xtend@~4.0.0, xtend@~4.0.1:
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
y18n@^3.2.1: y18n@^3.2.1:
version "3.2.1" version "3.2.2"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696"
integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==
y18n@^4.0.0: y18n@^4.0.0:
version "4.0.0" version "4.0.0"