Skip to content

Commit

Permalink
feat: add mullvad filter to lock page (#25)
Browse files Browse the repository at this point in the history
* feat: add mullvad filter to lock page

* fix: make ids on status page more specific

* fix: reduce debug log spam
  • Loading branch information
dkaser authored Nov 6, 2024
1 parent 5a67e88 commit c0e1983
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 119 deletions.
23 changes: 11 additions & 12 deletions src/usr/local/emhttp/plugins/tailscale/include/Pages/Status.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,16 @@
<script>

function controlsDisabled(val) {
$('#refresh').prop('disabled', val);
$('#statusTable_refresh').prop('disabled', val);
$('input.ping').prop('disabled', val);
$('#peersearch').prop('disabled', val);
}
function showStatus() {
controlsDisabled(true);
$.post('/plugins/tailscale/include/data/Status.php',{action: 'get',mullvad: $("#mullvad").prop('checked'), shared: $("#shared").prop('checked')},function(data){
$.post('/plugins/tailscale/include/data/Status.php',{action: 'get',mullvad: $("#statusTable_mullvad").prop('checked'), shared: $("#statusTable_shared").prop('checked')},function(data){
clearTimeout(timers.refresh);
$("#t1").trigger("destroy");
$('#t1').html(data.html);
$('#t1').tablesorter({
$("#statusTable").trigger("destroy");
$('#statusTable').html(data.html);
$('#statusTable').tablesorter({
widthFixed : true,
sortList: [[0,0]],
sortAppend: [[0,0]],
Expand All @@ -50,7 +49,7 @@ function showStatus() {
$('div.spinner.fixed').show('fast');
controlsDisabled(true);
var res = await $.post('/plugins/tailscale/include/data/Status.php',{action: 'ping', host: host});
$("#pingout").html("<strong>Ping response:</strong><br>" + res);
$("#status_pingout").html("<strong>Ping response:</strong><br>" + res);
showStatus();
}
showStatus();
Expand All @@ -65,15 +64,15 @@ function showStatus() {
}
</style>

<table id='t1' class="unraid t1 tablesorter"><tr><td><div class="spinner"></div></td></tr></table><br>
<table id='statusTable' class="unraid statusTable tablesorter"><tr><td><div class="spinner"></div></td></tr></table><br>
<table>
<tr>
<td style="vertical-align: top">
<input type="button" id="refresh" value="Refresh" onclick="showStatus()">
<input type="button" id="statusTable_refresh" value="Refresh" onclick="showStatus()">
<button type="button" class="reset">Reset Filters</button>
<input type="checkbox" id="mullvad" onChange="showStatus()">Display inactive Mullvad nodes
<input type="checkbox" id="shared" onChange="showStatus()">Display inactive shared-in nodes
<input type="checkbox" id="statusTable_mullvad" onChange="showStatus()">Display inactive Mullvad nodes
<input type="checkbox" id="statusTable_shared" onChange="showStatus()">Display inactive shared-in nodes
</td>
<td><div id="pingout" style="float: right;"></div></td>
<td><div id="status_pingout" style="float: right;"></div></td>
</tr>
</table>
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ public static function setPHPDebug(): void
if ((($version['BRANCH'] ?? "") == "trunk") && ! defined("TAILSCALE_TRUNK")) {
error_reporting(E_ALL);
define("TAILSCALE_TRUNK", true);
self::logmsg("Trunk plugin installed, enabling debug mode", true);
}
}

Expand Down
54 changes: 54 additions & 0 deletions src/usr/local/emhttp/plugins/tailscale/include/data/Lock.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace Tailscale;

try {
require_once "/usr/local/emhttp/plugins/tailscale/include/common.php";

$tailscaleConfig = $tailscaleConfig ?? new Config();
$tr = $tr ?? new Translator();

if ( ! $tailscaleConfig->Enable) {
echo("{}");
return;
}

switch ($_POST['action']) {
case 'get':
$tailscaleInfo = $tailscaleInfo ?? new Info($tr);
$rows = "";

$mullvad = filter_var($_POST['mullvad'] ?? false, FILTER_VALIDATE_BOOLEAN);

foreach ($tailscaleInfo->getTailscaleLockPending() as $lockHost => $lockKey) {
if ( ! $mullvad && str_contains($lockHost, 'mullvad.ts.net')) {
continue;
}

$rows .= "<tr><td><input type='checkbox' name='#arg[]' value='{$lockKey}' /></td><td>{$lockHost}</td><td>{$lockKey}</td></tr>";
}

$output = <<<EOT
<table id="lockTable" class="unraid lockTable">
<thead>
<tr>
<th class="filter-false">&nbsp;</th>
<th>Name</th>
<th class="filter-false">Key</th>
</tr>
</thead>
<tbody>
{$rows}
</tbody>
</table>
EOT;

$rtn = array();
$rtn['html'] = $output;
echo json_encode($rtn);
break;
}
} catch (\Throwable $e) {
file_put_contents("/var/log/tailscale-error.log", print_r($e, true) . PHP_EOL, FILE_APPEND);
echo "{}";
}
163 changes: 84 additions & 79 deletions src/usr/local/emhttp/plugins/tailscale/include/data/Status.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,96 +2,101 @@

namespace Tailscale;

require_once "/usr/local/emhttp/plugins/tailscale/include/common.php";
try {
require_once "/usr/local/emhttp/plugins/tailscale/include/common.php";

$tailscaleConfig = $tailscaleConfig ?? new Config();
$tr = $tr ?? new Translator();
$tailscaleConfig = $tailscaleConfig ?? new Config();
$tr = $tr ?? new Translator();

if ( ! $tailscaleConfig->Enable) {
echo("{}");
return;
}

switch ($_POST['action']) {
case 'get':
$tailscaleInfo = $tailscaleInfo ?? new Info($tr);
$rows = "";
if ( ! $tailscaleConfig->Enable) {
echo("{}");
return;
}

$mullvad = filter_var($_POST['mullvad'] ?? false, FILTER_VALIDATE_BOOLEAN);
$shared = filter_var($_POST['shared'] ?? false, FILTER_VALIDATE_BOOLEAN);
switch ($_POST['action']) {
case 'get':
$tailscaleInfo = $tailscaleInfo ?? new Info($tr);
$rows = "";

foreach ($tailscaleInfo->getPeerStatus() as $peer) {
if ($peer->Mullvad && ! $mullvad && ! $peer->Active) {
continue;
}
if ($peer->SharedUser && ! $shared && ! $peer->Active) {
continue;
}
$mullvad = filter_var($_POST['mullvad'] ?? false, FILTER_VALIDATE_BOOLEAN);
$shared = filter_var($_POST['shared'] ?? false, FILTER_VALIDATE_BOOLEAN);

$user = $peer->SharedUser ? $tr->tr('status_page.shared') : $peer->Name;
$online = $peer->Online ? ($peer->Active ? $tr->tr('status_page.active') : $tr->tr('status_page.idle')) : $tr->tr('status_page.offline');
$exitNode = $peer->ExitNodeActive ? $tr->tr('status_page.exit_active') : ($peer->ExitNodeAvailable ? ($peer->Mullvad ? "Mullvad" : $tr->tr('status_page.exit_available')) : "");
$connection = $peer->Active ? ($peer->Relayed ? $tr->tr('status_page.relay') : $tr->tr('status_page.direct')) : "";
$active = $peer->Active ? $peer->Address : "";
$txBytes = $peer->Traffic ? $peer->TxBytes : "";
$rxBytes = $peer->Traffic ? $peer->RxBytes : "";
$pingHost = ($peer->SharedUser || $peer->Active || ! $peer->Online || $peer->Mullvad) ? "" : "<input type='button' class='ping' value='Ping' onclick='pingHost(\"{$peer->Name}\")'>";
$ips = implode("<br />", $peer->IP);
foreach ($tailscaleInfo->getPeerStatus() as $peer) {
if ($peer->Mullvad && ! $mullvad && ! $peer->Active) {
continue;
}
if ($peer->SharedUser && ! $shared && ! $peer->Active) {
continue;
}

$rows .= <<<EOT
<tr>
<td>{$user}</td>
<td>{$ips}</td>
<td>{$peer->LoginName}</td>
<td>{$online}</td>
<td>{$exitNode}</td>
<td>{$connection}</td>
<td>{$active}</td>
<td>{$txBytes}</td>
<td>{$rxBytes}</td>
<td>{$pingHost}</td>
</tr>
EOT;
}
$user = $peer->SharedUser ? $tr->tr('status_page.shared') : $peer->Name;
$online = $peer->Online ? ($peer->Active ? $tr->tr('status_page.active') : $tr->tr('status_page.idle')) : $tr->tr('status_page.offline');
$exitNode = $peer->ExitNodeActive ? $tr->tr('status_page.exit_active') : ($peer->ExitNodeAvailable ? ($peer->Mullvad ? "Mullvad" : $tr->tr('status_page.exit_available')) : "");
$connection = $peer->Active ? ($peer->Relayed ? $tr->tr('status_page.relay') : $tr->tr('status_page.direct')) : "";
$active = $peer->Active ? $peer->Address : "";
$txBytes = $peer->Traffic ? $peer->TxBytes : "";
$rxBytes = $peer->Traffic ? $peer->RxBytes : "";
$pingHost = ($peer->SharedUser || $peer->Active || ! $peer->Online || $peer->Mullvad) ? "" : "<input type='button' class='ping' value='Ping' onclick='pingHost(\"{$peer->Name}\")'>";
$ips = implode("<br />", $peer->IP);

$output = <<<EOT
<table id="t1" class="unraid t1">
<thead>
$rows .= <<<EOT
<tr>
<th>{$tr->tr('info.dns')}</th>
<th>{$tr->tr('info.ip')}</th>
<th>{$tr->tr('status_page.login_name')}</th>
<th class="filter-select filter-match" id="status">{$tr->tr('status')}</th>
<th class="filter-select filter-match" id="exitnode">{$tr->tr('status_page.exit_node')}</th>
<th class="filter-select filter-match" id="conntype">{$tr->tr('status_page.connection_type')}</th>
<th class="filter-false">{$tr->tr('status_page.connection_addr')}</th>
<th class="filter-false">{$tr->tr('status_page.tx_bytes')}</th>
<th class="filter-false">{$tr->tr('status_page.rx_bytes')}</th>
<th class="filter-false">{$tr->tr('status_page.action')}</th>
<td>{$user}</td>
<td>{$ips}</td>
<td>{$peer->LoginName}</td>
<td>{$online}</td>
<td>{$exitNode}</td>
<td>{$connection}</td>
<td>{$active}</td>
<td>{$txBytes}</td>
<td>{$rxBytes}</td>
<td>{$pingHost}</td>
</tr>
</thead>
<tbody>
{$rows}
</tbody>
</table>
EOT;
EOT;
}

$output = <<<EOT
<table id="statusTable" class="unraid statusTable">
<thead>
<tr>
<th>{$tr->tr('info.dns')}</th>
<th>{$tr->tr('info.ip')}</th>
<th>{$tr->tr('status_page.login_name')}</th>
<th class="filter-select filter-match" id="status">{$tr->tr('status')}</th>
<th class="filter-select filter-match" id="exitnode">{$tr->tr('status_page.exit_node')}</th>
<th class="filter-select filter-match" id="conntype">{$tr->tr('status_page.connection_type')}</th>
<th class="filter-false">{$tr->tr('status_page.connection_addr')}</th>
<th class="filter-false">{$tr->tr('status_page.tx_bytes')}</th>
<th class="filter-false">{$tr->tr('status_page.rx_bytes')}</th>
<th class="filter-false">{$tr->tr('status_page.action')}</th>
</tr>
</thead>
<tbody>
{$rows}
</tbody>
</table>
EOT;

$rtn = array();
$rtn['html'] = $output;
echo json_encode($rtn);
break;
case 'ping':
$tailscaleInfo = $tailscaleInfo ?? new Info($tr);
$out = "Could not find host.";
$rtn = array();
$rtn['html'] = $output;
echo json_encode($rtn);
break;
case 'ping':
$tailscaleInfo = $tailscaleInfo ?? new Info($tr);
$out = "Could not find host.";

foreach ($tailscaleInfo->getPeerStatus() as $peer) {
if ($peer->Name == $_POST['host']) {
$peerIP = escapeshellarg($peer->IP[0]);
$out = implode("<br>", Utils::run_command("tailscale ping {$peerIP}"));
break;
foreach ($tailscaleInfo->getPeerStatus() as $peer) {
if ($peer->Name == $_POST['host']) {
$peerIP = escapeshellarg($peer->IP[0]);
$out = implode("<br>", Utils::run_command("tailscale ping {$peerIP}"));
break;
}
}
}

echo $out;
break;
echo $out;
break;
}
} catch (\Throwable $e) {
file_put_contents("/var/log/tailscale-error.log", print_r($e, true) . PHP_EOL, FILE_APPEND);
echo "{}";
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,17 @@
}
?>

<form markdown="1" method="POST" action="/update.php" target="progressFrame">
<input type="hidden" name="#command" value="/usr/local/emhttp/plugins/tailscale/approve-nodes.php" />
<table class="unraid t2 tablesorter" id="t2">
<thead>
<tr>
<th class="filter-false">&nbsp;</th>
<th>Name</th>
<th class="filter-false">Key</th>
</tr>
</thead>
<tbody>
<?php
foreach ($tailscaleInfo->getTailscaleLockPending() as $lockHost => $lockKey) {
echo "<tr><td><input type='checkbox' name='#arg[]' value='{$lockKey}' /></td><td>{$lockHost}</td><td>{$lockKey}</td></tr>";
}
?>
</tbody>
</table>

<input type="submit" name="#apply" value="<?= $tr->tr('Sign'); ?>">
</form>
<script>
function showLocks() {
$('#t2').tablesorter({
function controlsDisabled(val) {
$('#lockTable_signnode').prop('disabled', val);
}
function loadFilteredPeers() {
controlsDisabled(true);
$.post('/plugins/tailscale/include/data/Lock.php',{action: 'get',mullvad: $("#lockTable_mullvad").prop('checked')},function(data){
clearTimeout(timers.refresh);
$("#lockTable").trigger("destroy");
$('#lockTable').html(data.html);
$('#lockTable').tablesorter({
widthFixed : true,
sortList: [[0,0]],
sortAppend: [[0,0]],
Expand All @@ -49,11 +36,19 @@ function showLocks() {
// on azure and gray, offset is height of #header
stickyHeaders_offset: ($('#menu').height() < 50) ? $('#menu').height() : $('#header').height(),
filter_columnFilters: true,
filter_liveSearch: true,

zebra: ["normal-row","alt-row"]
}
});
controlsDisabled(false);
},"json");
}
showLocks();
</script>
loadFilteredPeers();
</script>

<form method="POST" action="/update.php" target="progressFrame">
<input type="hidden" name="#command" value="/usr/local/emhttp/plugins/tailscale/approve-nodes.php" />
<table id='lockTable' class="unraid lockTable tablesorter"><tr><td>&nbsp;</td></tr></table><br>

<input type="submit" id="lockTable_signnode" name="#apply" value="<?= $tr->tr('Sign'); ?>">
<input type="checkbox" id="lockTable_mullvad" onChange="loadFilteredPeers()">Display unsigned Mullvad nodes
</form>

0 comments on commit c0e1983

Please sign in to comment.