diff --git a/config.php.dist b/config.php.dist index 2963b9c..de8f49e 100644 --- a/config.php.dist +++ b/config.php.dist @@ -25,12 +25,14 @@ $options = [ 'tableitems' => 30, // records limit on alive, all, search pages /* Records processing options */ - 'approvedelay' => 24, // check host for availability before publishing for this time (hours) - 'approveseen' => 3, // host must be seen lesser than this amount of hours for approving (hours) + 'approvedelay' => 24, // check host for availability before publishing for this time (hours) + 'approveseen' => 3, // host must be seen lesser than this amount of hours for approving (hours) 'newdays' => 14, // assume host as new for that amout of days + 'olddays' => 45, // assume host as approved if seen less than that amount of days, and stable if seen more than that amount of days 'delnewdays' => 3, // if new host not seen more than X days, disable it and disapprove - 'delolddays' => 45, // same as above, but for old hosts + 'delapprdays' => 45, // same as above, but for old hosts + 'delstabdays' => 180, // same as above, but for old hosts 'hidedays' => 3, // days before domain will be marked as hidden in period before disabling diff --git a/export.php b/export.php index a5bffdc..bd6c0de 100644 --- a/export.php +++ b/export.php @@ -11,38 +11,39 @@ $util = new App\Utils; $STH = $pdo->query ("SELECT `host`, `base64`, `base32`, `add_date`, `last_seen`, `approved`, `initial`, `disabled`, `hidden` FROM hosts"); $hosts = $STH->fetchAll(PDO::FETCH_ASSOC); +$curr_time = time(); + // for automatic approving -$approffs = date ("Y-m-d H:i:s", strtotime ("-" . $options["approvedelay"] . " hour")); // approval offset -$apprseen = date ("Y-m-d H:i:s", strtotime ("-" . $options["approveseen"] . " hour")); // approval maxseen offset +$approffs = $options["approvedelay"] * 3600; +$apprseen = $options["approveseen"] * 3600; + +// for managing export and disabling +$newregoffs = $options["newdays"] * 86400; +$oldregoffs = $options["olddays"] * 86400; -$newregoffs = date ("Y-m-d H:i:s", strtotime ("-" . $options["newdays"] . " day")); -$newseenlim = date ("Y-m-d H:i:s", strtotime ("-" . $options["delnewdays"] . " day")); -$oldseenlim = date ("Y-m-d H:i:s", strtotime ("-" . $options["delolddays"] . " day")); +$newseenlim = $options["delnewdays"] * 86400; +$appseenlim = $options["delapprdays"] * 86400; +$staseenlim = $options["delstabdays"] * 86400; -$hideoffs = date ("Y-m-d H:i:s", strtotime ("-" . $options["hidedays"] . " day")); // hide offset +$hideoffs = $options["hidedays"] * 86400; $export_full = $export_live = $export_init = []; $export_addr_full = $export_addr_live = $export_addr_init = []; foreach ($hosts as $host) { - /* Convert UFT-8 domains to Punycode */ + /* Convert UTF-8 domains to Punycode */ $domain = $util->isASCII ($host["host"]) ? $host["host"] : idn_to_ascii ($host["host"]); + $add_date = strtotime ($host["add_date"]); + $last_seen = strtotime ($host["last_seen"]); + array_push($export_full, $domain . "=" . $host["base64"]); array_push($export_addr_full, $domain . "," . $host["base32"]); - if ( - ($options["approval"] == false || $host["approved"] == 1) && $host["hidden"] == 0 && - ($host["disabled"] == 0 || - ( - ($host["add_date"] > $newregoffs && $host["last_seen"] > $newseenlim) || - ($host["add_date"] < $newregoffs && $host["last_seen"] > $oldseenlim) // is seen till disabling date - ) - ) - ) + if (($options["approval"] == false || $host["approved"] == 1) && $host["hidden"] == 0 && $host["disabled"] == 0) { - if ($host["last_seen"] > $hideoffs) { // if seen not earlier than hide offset + if (($last_seen + $hideoffs) > $curr_time) { array_push($export_live, $domain . "=" . $host["base64"]); array_push($export_addr_live, $domain . "," . $host["base32"]); @@ -52,14 +53,14 @@ foreach ($hosts as $host) array_push($export_addr_init, $domain . "," . $host["base32"]); } } - else // hide because not available for "hidedays" days + else // hide because not available for X days { $pdo->exec ("UPDATE `hosts` SET `hidden` = 1 WHERE `host` = '" . $host["host"] . "'"); } } else if ( $host["approved"] == 0 && ( - ($host["add_date"] < $approffs && $host["last_seen"] > $apprseen) // if host were registered more then X days ago and seen lesser than X hours ago + (($add_date + $approffs) < $curr_time && ($last_seen + $apprseen) > $curr_time) ) ) { @@ -70,8 +71,11 @@ foreach ($hosts as $host) if ( $host["disabled"] == 0 && - ($host["add_date"] > $newregoffs && $host["last_seen"] < $newseenlim) || - ($host["add_date"] < $newregoffs && $host["last_seen"] < $oldseenlim) // is seen more that disabling period days + ( + (($last_seen - $add_date) < $newregoffs && ($last_seen + $newseenlim) < $curr_time) || + (($last_seen - $add_date) < $oldregoffs && ($last_seen + $appseenlim) < $curr_time) || + (($last_seen - $add_date) > $oldregoffs && ($last_seen + $staseenlim) < $curr_time) + ) ) { $pdo->exec ("UPDATE `hosts` SET `disabled` = 1 WHERE `host` = '" . $host["host"] . "'"); @@ -85,10 +89,10 @@ $pdo = null; /* Sort records */ sort ($export_full); sort ($export_addr_full); -// + sort ($export_live); sort ($export_addr_live); -// + sort ($export_init); sort ($export_addr_init); diff --git a/fetch.php b/fetch.php index aceda46..3a752f1 100644 --- a/fetch.php +++ b/fetch.php @@ -55,7 +55,7 @@ foreach ($lists as $list) { $domain = ""; $record = $util->parseHostRecord($buffer); - if (!$util->isValidAddress($record['host'], $error)) { + if (!$util->isValidDomain($record['host'], $error)) { echo "Error while validating " . $record['host'] . ": " . $error . PHP_EOL; continue; diff --git a/import.php b/import.php index f07fba7..feac334 100644 --- a/import.php +++ b/import.php @@ -20,7 +20,7 @@ if ($f) { $domain = ""; $record = $util->parseHostRecord($buffer); - if (!$util->isValidAddress($record['host'], $error)) { + if (!$util->isValidDomain($record['host'], $error)) { echo "Error while validating " . $record['host'] . ": " . $error . PHP_EOL; continue; diff --git a/lib/utils.php b/lib/utils.php index 248efa4..7b9d946 100644 --- a/lib/utils.php +++ b/lib/utils.php @@ -144,41 +144,6 @@ class Utils { return self::b32encode(hash('sha256', self::b64decode($data), true)); } - /** - * Domain validation function for registration. - * @param string $data - * @return bool - */ - public static function isValidAddress(string $data, string &$result): bool - { - $len = strlen($data); - - if($len < 5 || $len > 255) // rfc2181, section 11 - { - $result = "Domain must be longer than 5 and lesser than 255 chars."; - return false; - } - - if(preg_match('/\.b32\.i2p$/', $data)) - { - $result = "Domain can't end with .b32.i2p."; - return false; - } - - if(filter_var($data, FILTER_VALIDATE_DOMAIN) !== false && preg_match('/\.i2p$/', $data) - && (static::isPunycodeDomain($data) || static::isAscii($data))) - { - return true; - } - else - { - $result = "Domain is not valid. Check if you domain label is lesser than 63 chars, and uses only ASCII or Punycode format."; - return false; - } - - return false; - } - /** * Domain validation function. * @param string $data @@ -204,12 +169,8 @@ class Utils { { return true; } - else - { - $result = "Inputed data or domain is not valid."; - return false; - } + $result = "Domain is not valid. Check if you domain label is lesser than 63 chars and it ends with .i2p."; return false; } @@ -217,6 +178,9 @@ class Utils { { $retval = null; + if (strpos($data, "&") !== false) + return false; // registration string can't have ampersands + $cmd = dirname(__FILE__) . "/../bin/verifyhost '" . $data . "'"; exec($cmd, $output, $retval); diff --git a/templates/add.twig b/templates/add.twig index 829a565..084a738 100644 --- a/templates/add.twig +++ b/templates/add.twig @@ -13,7 +13,15 @@ {% else %}
-

Domain successfuly added

+ {% if result.command == 'addname' %} +

Domain alias successfuly added

+ {% elseif result.command == 'addsubdomain' %} +

Subdomain successfuly added

+ {% elseif result.command == 'changedest' %} +

Domain destination successfuly changed

+ {% else %} +

Domain successfuly added

+ {% endif %}
Domain: diff --git a/templates/home.twig b/templates/home.twig index a46fa68..19a9983 100644 --- a/templates/home.twig +++ b/templates/home.twig @@ -15,6 +15,7 @@
  • adding of hosts for 2LD domains (example.i2p)
  • adding subdomains (addsubdomain)
  • adding/changing destination (adddest, changedest) - destination is replaced with the new one, old destination is purged
  • +
  • adding domain alias (addname) - alias must be 2LD (example.i2p). For registering subdomains as aliases please use addsubdomain command
  • @@ -38,11 +39,11 @@

    Rules:
    Although there are no specific rules for domain registration, we do have the policy on dead domain records.
    - Your domain will become open for registration again if it is dead for: + Your domain will become open for registration again (disabled) if it is dead for:

      -
    • {{ delnewdays }} days if registered less than {{ newdays }} days ago
    • -
    • {{ delolddays }} days if registered more than {{ newdays }} days ago
    • -
    • 1 year if registered more than {{ delolddays }} days ago
    • +
    • {{ delnewdays }} days if last seen less than {{ newdays }} days since registration
    • +
    • {{ delapprdays }} days if last seen less than {{ olddays }} days since registration
    • +
    • {{ delstabdays }} days if last seen more than {{ olddays }} days since registration
    Domains that are inaccessible before the disabling date for {{ hidedays }} days, will be hidden from alive list, removed from export lists, but will still be checked every hour.
    When domain dead for amount days stated above, it will be marked as disabled, opened for registration and will be checked once a day for availability at {{ fullhour }} o'clock UTC. diff --git a/templates/latest.twig b/templates/latest.twig index 84d0453..ac0dc62 100644 --- a/templates/latest.twig +++ b/templates/latest.twig @@ -16,7 +16,7 @@ AH B32 Full Base32 - Added + Added @@ -30,7 +30,7 @@ A B {{ host.base32 }}.b32.i2p - {{ host.add_date }} + {{ host.add_date }} {% endfor %} diff --git a/views/add.php b/views/add.php index c5329e2..41ced08 100644 --- a/views/add.php +++ b/views/add.php @@ -28,7 +28,7 @@ if (isset($_POST["record"]) && !empty($_POST["record"])) { $parsed = $util->parseHostRecord($record); - if (!$util->isValidAddress($parsed['host'], $error)) { + if (!$util->isValidDomain($parsed['host'], $error)) { $result["error"] = "Error while validating: " . $error; } else { if ($util->isPunycodeDomain($parsed['host'])) { @@ -37,105 +37,128 @@ if (isset($_POST["record"]) && !empty($_POST["record"])) { $domain = $parsed['host']; } - /* Check if such domain name already registered */ - $STH = $pdo->query("SELECT COUNT(*) FROM `hosts` WHERE `host` = '" . $domain . "' LIMIT 1"); + if (!isset($parsed["commands"]) || !isset($parsed["commands"]["sig"])) { + $result["error"] = "Error while validating: No extended record fields or signature is found."; - if($STH->fetchColumn() == 1) { - $result["error"] = "Error while validating: That domain is already registered."; + } else if (!$util->verifyHostRecord($record, $error)) { + $result["error"] = "Error while validating: " . $error[0]; } else { - if (!isset($parsed["commands"]) || !isset($parsed["commands"]["sig"])) { - $result["error"] = "Error while validating: No extended record fields or signature is found."; + /* Check if such domain name already registered */ + $STH = $pdo->query("SELECT COUNT(*) FROM `hosts` WHERE `host` = '" . $domain . "' LIMIT 1"); - } else if (!$util->verifyHostRecord($record, $error)) { - $result["error"] = "Error while validating: " . $error[0]; + if (isset($parsed["commands"]["action"])) { + switch ($parsed["commands"]["action"]) { + case 'addsubdomain': + if ($STH->fetchColumn() == 1) { + $result["error"] = "Error while validating: That subdomain is already registered."; - } else { - if (isset($parsed["commands"]["action"])) { - switch ($parsed["commands"]["action"]) { - case 'addsubdomain': - if (!isset($parsed["commands"]["oldname"]) || !isset($parsed["commands"]["olddest"]) || !isset($parsed["commands"]["oldsig"])) { - $result["error"] = "Error while validating: required fields not found. Re-check your registration string."; + } else if (!isset($parsed["commands"]["oldname"]) || !isset($parsed["commands"]["olddest"]) || !isset($parsed["commands"]["oldsig"])) { + $result["error"] = "Error while validating: required fields not found. Re-check your registration string."; - } else { - /* Getting domain at higher level (2LD for registering 3LD and etc.) and validating that domain is lower than 2LD. */ - $darr = explode(".", $domain); - $dtop = ""; + } else { + /* Getting domain at higher level (2LD for registering 3LD and etc.) and validating that domain is lower than 2LD. */ + $darr = explode(".", $domain); + $dtop = ""; - for ($i = 1; $i < sizeof ($darr); $i++) { - $dtop .= $darr[$i]; - if ((sizeof ($darr) - 1) != $i) $dtop .= "."; - } + for ($i = 1; $i < sizeof ($darr); $i++) { + $dtop .= $darr[$i]; + if ((sizeof ($darr) - 1) != $i) $dtop .= "."; + } + + if (sizeof($darr) < 3) { + $result["error"] = "Error while validating: you can't register second level domain (example.i2p) using addsubdomain action."; - if (sizeof($darr) < 3) { - $result["error"] = "Error while validating: you can't register second level domain (example.i2p) using addsubdomain action."; + } else if ($dtop != $parsed["commands"]["oldname"]) { + $result["error"] = "Error while validating: oldname value is not same as your higher level domain."; - } else if ($dtop != $parsed["commands"]["oldname"]) { - $result["error"] = "Error while validating: oldname value is not same as your higher level domain."; + } else if (!$pdo->query("SELECT COUNT(*) FROM `hosts` WHERE `host` = '" . $parsed["commands"]["oldname"] . "' AND `base64` = '" . $parsed["commands"]["olddest"] . "' LIMIT 1")->fetchColumn()) { + $result["error"] = "Error while validating: can't find higher level domain with values from oldname and olddest."; - } else if (!$pdo->query("SELECT COUNT(*) FROM `hosts` WHERE `host` = '" . $parsed["commands"]["oldname"] . "' AND `base64` = '" . $parsed["commands"]["olddest"] . "' LIMIT 1")->fetchColumn()) { - $result["error"] = "Error while validating: can't find higher level domain with values from oldname and olddest."; + } else { + $base32 = $util->b32from64($parsed["b64"]); + if (!$pdo->exec("INSERT INTO `hosts` (`host`, `base64`, `base32`) VALUES ('" . $domain . "', '" . $parsed["b64"] . "', '" . $base32 . "')")) { + $result["error"] = "Error happened while inserting record to database. Please try again later."; } else { - $base32 = $util->b32from64($parsed["b64"]); - if (!$pdo->exec("INSERT INTO `hosts` (`host`, `base64`, `base32`) VALUES ('" . $domain . "', '" . $parsed["b64"] . "', '" . $base32 . "')")) { - $result["error"] = "Error happened while inserting record to database. Please try again later."; - - } else { - $result["host"] = $domain; - $result["base64"] = $parsed["b64"]; - $result["base32"] = $base32; - } + $result["command"] = 'addsubdomain'; + $result["host"] = $domain; + $result["base64"] = $parsed["b64"]; + $result["base32"] = $base32; } } - break; - case 'adddest': - case 'changedest': - if (!isset($parsed["commands"]["olddest"]) || !isset($parsed["commands"]["oldsig"])) { - $result["error"] = "Error while validating: required fields not found. Re-check your registration string."; + } + break; + case 'adddest': + case 'changedest': + if($STH->fetchColumn() == 0) { + $result["error"] = "Error while validating: That domain is not registered."; + + } else if (!isset($parsed["commands"]["olddest"]) || !isset($parsed["commands"]["oldsig"])) { + $result["error"] = "Error while validating: required fields not found. Re-check your registration string."; + + } else { + if (!$pdo->query("SELECT COUNT(*) FROM `hosts` WHERE `host` = '" . $domain . "' AND `base64` = '" . $parsed["commands"]["olddest"] . "' LIMIT 1")->fetchColumn()) { + $result["error"] = "Error while validating: old base64 and value in olddest field does not match.."; } else { - if (!$pdo->query("SELECT COUNT(*) FROM `hosts` WHERE `host` = '" . $domain . "' AND `base64` = '" . $parsed["commands"]["olddest"] . "' LIMIT 1")->fetchColumn()) { - $result["error"] = "Error while validating: old base64 and value in olddest field does not match.."; + $base32 = $util->b32from64($parsed["b64"]); + if (!$pdo->exec("UPDATE `hosts` SET `base64` = '" . $parsed["b64"] . "', `base32` = '" . $base32 . "' WHERE `host` = '" . $domain . "'")) { + $result["error"] = "Error happened while updating record in database. Please try again later."; } else { - $base32 = $util->b32from64($parsed["b64"]); - if (!$pdo->exec("UPDATE `hosts` SET `base64` = '" . $parsed["b64"] . "', `base32` = '" . $base32 . "' WHERE `host` = '" . $domain . "'")) { - $result["error"] = "Error happened while updating record in database. Please try again later."; - - } else { - $result["host"] = $domain; - $result["base64"] = $parsed["b64"]; - $result["base32"] = $base32; - } + $result["command"] = 'changedest'; + $result["host"] = $domain; + $result["base64"] = $parsed["b64"]; + $result["base32"] = $base32; } } - break; - case 'addname': - if (!isset($parsed["commands"]["olddest"]) || !isset($parsed["commands"]["oldsig"])) { - $result["error"] = "Error while validating: required fields not found. Re-check your registration string."; + } + break; + case 'addname': + if($STH->fetchColumn() == 1) { + $result["error"] = "Error while validating: That domain is already registered."; + + /* Getting domain level (2LD, 3LD and etc.) and validating that domain at higher level is registered (2LD if registering 3LD). */ + } else if (sizeof(explode(".", $domain)) > 2) { + $result["error"] = "Error while validating: you can't register subdomain (sub.example.i2p) as domain alias using addname action."; + + } else if (!isset($parsed["commands"]["oldname"])) { + $result["error"] = "Error while validating: required fields not found. Re-check your registration string."; + + } else { + if ($util->isPunycodeDomain($parsed["commands"]["oldname"])) { + $olddomain = idn_to_utf8($parsed["commands"]["oldname"], 0, INTL_IDNA_VARIANT_UTS46); + + } else { + $olddomain = $parsed["commands"]["oldname"]; + } + + if (!$pdo->query("SELECT COUNT(*) FROM `hosts` WHERE `host` = '" . $olddomain . "' AND `base64` = '" . parsed["b64"] . "' LIMIT 1")->fetchColumn()) { + $result["error"] = "Error while validating: base64 does not match for domain in oldname field..."; } else { - if (!$pdo->query("SELECT COUNT(*) FROM `hosts` WHERE `host` = '" . $domain . "' AND `base64` = '" . $parsed["commands"]["olddest"] . "' LIMIT 1")->fetchColumn()) { - $result["error"] = "Error while validating: old base64 and value in olddest field does not match.."; + $base32 = $util->b32from64($parsed["b64"]); + if (!$pdo->exec("INSERT INTO `hosts` (`host`, `base64`, `base32`) VALUES ('" . $domain . "', '" . $parsed["b64"] . "', '" . $base32 . "')")) { + $result["error"] = "Error happened while updating record in database. Please try again later."; } else { - $base32 = $util->b32from64($parsed["b64"]); - if (!$pdo->exec("UPDATE `hosts` SET `base64` = '" . $parsed["b64"] . "', `base32` = '" . $base32 . "' WHERE `host` = '" . $domain . "'")) { - $result["error"] = "Error happened while updating record in database. Please try again later."; - - } else { - $result["host"] = $domain; - $result["base64"] = $parsed["b64"]; - $result["base32"] = $base32; - } + $result["command"] = 'addname'; + $result["host"] = $domain; + $result["base64"] = $parsed["b64"]; + $result["base32"] = $base32; } } - break; - default: - $result["error"] = "Error while validating: extended record fields are NOT supported for now."; - break; - } + } + break; + default: + $result["error"] = "Error while validating: extended record fields are NOT supported."; + break; + } + + } else { + if($STH->fetchColumn() == 1) { + $result["error"] = "Error while validating: That domain is already registered."; } else { if (isset($parsed["commands"]["oldname"]) || isset($parsed["commands"]["olddest"]) || isset($parsed["commands"]["oldsig"])) { @@ -152,9 +175,10 @@ if (isset($_POST["record"]) && !empty($_POST["record"])) { $result["error"] = "Error happened while inserting record to database. Please try again later."; } else { - $result["host"] = $domain; - $result["base64"] = $parsed["b64"]; - $result["base32"] = $base32; + $result["command"] = 'added'; + $result["host"] = $domain; + $result["base64"] = $parsed["b64"]; + $result["base32"] = $base32; } } } diff --git a/views/alive.php b/views/alive.php index 89b5221..c85d729 100644 --- a/views/alive.php +++ b/views/alive.php @@ -11,18 +11,12 @@ $twig = new \Twig\Environment($loader, [ ]); $offset = $options["tableitems"] * ($page - 1); -$newregoffs = date ("Y-m-d H:i:s", strtotime ("-7 day")); -$newseenlim = date ("Y-m-d H:i:s", strtotime ("-3 day")); -$oldseenlim = date ("Y-m-d H:i:s", strtotime ("-7 day")); $pdo = (new App\DB($options))->pdo; /* Get records amount */ $STH = $pdo->query ("SELECT COUNT(*) as `count` FROM `hosts` " . - "WHERE `approved` = 1 AND `disabled` = 0 AND `hidden` = 0 AND (" . - " (`add_date` < '" . $newregoffs . "' AND `last_seen` > '" . $oldseenlim . "') OR" . - " (`add_date` > '" . $newregoffs . "' AND `last_seen` > '" . $newseenlim . "')" . - ")"); + "WHERE `approved` = 1 AND `disabled` = 0 AND `hidden` = 0"); $STH->setFetchMode (PDO::FETCH_ASSOC); $records = $STH->fetch()["count"]; @@ -30,10 +24,8 @@ $pages = intdiv($records, $options["tableitems"]) + 1; /* Get records with limit */ $STH = $pdo->query ("SELECT `host`, `base64`, `base32`, `last_seen` FROM `hosts` " . - "WHERE `approved` = 1 AND `disabled` = 0 AND `hidden` = 0 AND (" . - " (`add_date` < '" . $newregoffs . "' AND `last_seen` > '" . $oldseenlim . "') OR" . - " (`add_date` > '" . $newregoffs . "' AND `last_seen` > '" . $newseenlim . "')" . - ") LIMIT " . $offset . ", " . $options["tableitems"]); + "WHERE `approved` = 1 AND `disabled` = 0 AND `hidden` = 0 " . + "LIMIT " . $offset . ", " . $options["tableitems"]); $STH->setFetchMode(PDO::FETCH_ASSOC); $rows = $STH->fetchAll(); diff --git a/views/home.php b/views/home.php index bdc97bd..ecb35a4 100644 --- a/views/home.php +++ b/views/home.php @@ -21,16 +21,18 @@ if ($options['fetcher']) { } $vars = array( - 'approval' => $options['approval'], - 'apprdelay' => $options['approvedelay'], - 'apprseen' => $options['approveseen'], - 'newdays' => $options['newdays'], - 'delnewdays' => $options['delnewdays'], - 'delolddays' => $options['delolddays'], - 'hidedays' => $options['hidedays'], - 'fullhour' => $options['fullhour'], - 'fetcher' => $options['fetcher'], - 'subscrs' => $subscrs + 'approval' => $options['approval'], + 'apprdelay' => $options['approvedelay'], + 'apprseen' => $options['approveseen'], + 'newdays' => $options['newdays'], + 'olddays' => $options['olddays'], + 'delnewdays' => $options['delnewdays'], + 'delapprdays' => $options['delapprdays'], + 'delstabdays' => $options['delstabdays'], + 'hidedays' => $options['hidedays'], + 'fullhour' => $options['fullhour'], + 'fetcher' => $options['fetcher'], + 'subscrs' => $subscrs ); $template = $twig->load('home.twig'); diff --git a/views/latest.php b/views/latest.php index f682ed7..0c1d77d 100644 --- a/views/latest.php +++ b/views/latest.php @@ -13,7 +13,7 @@ $twig = new \Twig\Environment($loader, [ $pdo = (new App\DB($options))->pdo; /* Get records with limit */ -$STH = $pdo->query ("SELECT `host`, `base64`, `base32`, `add_date` FROM `hosts` WHERE `disabled` = 0 ORDER BY `add_date` DESC LIMIT " . $options["tableitems"]); +$STH = $pdo->query ("SELECT `host`, `base64`, `base32`, `add_date`, `last_seen` FROM `hosts` WHERE `disabled` = 0 ORDER BY `add_date` DESC LIMIT " . $options["tableitems"]); $STH->setFetchMode(PDO::FETCH_ASSOC); $rows = $STH->fetchAll();