added DNS resolver
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,3 +4,4 @@ composer.lock
|
|||||||
requests.sqlite3
|
requests.sqlite3
|
||||||
requests.sqlite3-shm
|
requests.sqlite3-shm
|
||||||
requests.sqlite3-wal
|
requests.sqlite3-wal
|
||||||
|
GeoLite2-City.mmdb
|
||||||
@@ -6,7 +6,9 @@
|
|||||||
"react/cache": "^1.2",
|
"react/cache": "^1.2",
|
||||||
"clue/mq-react": "^1.6",
|
"clue/mq-react": "^1.6",
|
||||||
"smarty/smarty": "^5.4",
|
"smarty/smarty": "^5.4",
|
||||||
"react/promise-timer": "^1.11"
|
"react/promise-timer": "^1.11",
|
||||||
|
"geoip2/geoip2": "~2.0",
|
||||||
|
"maxmind-db/reader": "~1.0"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
|||||||
250
composer.lock
generated
250
composer.lock
generated
@@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "8e299b08324c21b9f02c215ffc70c444",
|
"content-hash": "d6f1f7467007dba97d491d18cbdfc5d6",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "clue/framework-x",
|
"name": "clue/framework-x",
|
||||||
@@ -279,6 +279,82 @@
|
|||||||
],
|
],
|
||||||
"time": "2023-05-12T12:33:20+00:00"
|
"time": "2023-05-12T12:33:20+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "composer/ca-bundle",
|
||||||
|
"version": "1.5.4",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/composer/ca-bundle.git",
|
||||||
|
"reference": "bc0593537a463e55cadf45fd938d23b75095b7e1"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/composer/ca-bundle/zipball/bc0593537a463e55cadf45fd938d23b75095b7e1",
|
||||||
|
"reference": "bc0593537a463e55cadf45fd938d23b75095b7e1",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-openssl": "*",
|
||||||
|
"ext-pcre": "*",
|
||||||
|
"php": "^7.2 || ^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpstan/phpstan": "^1.10",
|
||||||
|
"phpunit/phpunit": "^8 || ^9",
|
||||||
|
"psr/log": "^1.0 || ^2.0 || ^3.0",
|
||||||
|
"symfony/process": "^4.0 || ^5.0 || ^6.0 || ^7.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-main": "1.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Composer\\CaBundle\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Jordi Boggiano",
|
||||||
|
"email": "j.boggiano@seld.be",
|
||||||
|
"homepage": "http://seld.be"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.",
|
||||||
|
"keywords": [
|
||||||
|
"cabundle",
|
||||||
|
"cacert",
|
||||||
|
"certificate",
|
||||||
|
"ssl",
|
||||||
|
"tls"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"irc": "irc://irc.freenode.org/composer",
|
||||||
|
"issues": "https://github.com/composer/ca-bundle/issues",
|
||||||
|
"source": "https://github.com/composer/ca-bundle/tree/1.5.4"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://packagist.com",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/composer",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2024-11-27T15:35:25+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "evenement/evenement",
|
"name": "evenement/evenement",
|
||||||
"version": "v3.0.2",
|
"version": "v3.0.2",
|
||||||
@@ -382,6 +458,64 @@
|
|||||||
},
|
},
|
||||||
"time": "2020-11-24T22:02:12+00:00"
|
"time": "2020-11-24T22:02:12+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "geoip2/geoip2",
|
||||||
|
"version": "v2.13.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/maxmind/GeoIP2-php.git",
|
||||||
|
"reference": "6a41d8fbd6b90052bc34dff3b4252d0f88067b23"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/maxmind/GeoIP2-php/zipball/6a41d8fbd6b90052bc34dff3b4252d0f88067b23",
|
||||||
|
"reference": "6a41d8fbd6b90052bc34dff3b4252d0f88067b23",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-json": "*",
|
||||||
|
"maxmind-db/reader": "~1.8",
|
||||||
|
"maxmind/web-service-common": "~0.8",
|
||||||
|
"php": ">=7.2"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"friendsofphp/php-cs-fixer": "3.*",
|
||||||
|
"phpstan/phpstan": "*",
|
||||||
|
"phpunit/phpunit": "^8.0 || ^9.0",
|
||||||
|
"squizlabs/php_codesniffer": "3.*"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"GeoIp2\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"Apache-2.0"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Gregory J. Oschwald",
|
||||||
|
"email": "goschwald@maxmind.com",
|
||||||
|
"homepage": "https://www.maxmind.com/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "MaxMind GeoIP2 PHP API",
|
||||||
|
"homepage": "https://github.com/maxmind/GeoIP2-php",
|
||||||
|
"keywords": [
|
||||||
|
"IP",
|
||||||
|
"geoip",
|
||||||
|
"geoip2",
|
||||||
|
"geolocation",
|
||||||
|
"maxmind"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/maxmind/GeoIP2-php/issues",
|
||||||
|
"source": "https://github.com/maxmind/GeoIP2-php/tree/v2.13.0"
|
||||||
|
},
|
||||||
|
"time": "2022-08-05T20:32:58+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "graham-campbell/result-type",
|
"name": "graham-campbell/result-type",
|
||||||
"version": "v1.1.3",
|
"version": "v1.1.3",
|
||||||
@@ -444,6 +578,120 @@
|
|||||||
],
|
],
|
||||||
"time": "2024-07-20T21:45:45+00:00"
|
"time": "2024-07-20T21:45:45+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "maxmind-db/reader",
|
||||||
|
"version": "v1.12.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/maxmind/MaxMind-DB-Reader-php.git",
|
||||||
|
"reference": "5b2d7a721dedfaef9dc20822c5fe7d26f9f8eb90"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/maxmind/MaxMind-DB-Reader-php/zipball/5b2d7a721dedfaef9dc20822c5fe7d26f9f8eb90",
|
||||||
|
"reference": "5b2d7a721dedfaef9dc20822c5fe7d26f9f8eb90",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.2"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"ext-maxminddb": "<1.11.1 || >=2.0.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"friendsofphp/php-cs-fixer": "3.*",
|
||||||
|
"phpstan/phpstan": "*",
|
||||||
|
"phpunit/phpunit": ">=8.0.0,<10.0.0",
|
||||||
|
"squizlabs/php_codesniffer": "3.*"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-bcmath": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder",
|
||||||
|
"ext-gmp": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder",
|
||||||
|
"ext-maxminddb": "A C-based database decoder that provides significantly faster lookups"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"MaxMind\\Db\\": "src/MaxMind/Db"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"Apache-2.0"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Gregory J. Oschwald",
|
||||||
|
"email": "goschwald@maxmind.com",
|
||||||
|
"homepage": "https://www.maxmind.com/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "MaxMind DB Reader API",
|
||||||
|
"homepage": "https://github.com/maxmind/MaxMind-DB-Reader-php",
|
||||||
|
"keywords": [
|
||||||
|
"database",
|
||||||
|
"geoip",
|
||||||
|
"geoip2",
|
||||||
|
"geolocation",
|
||||||
|
"maxmind"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/maxmind/MaxMind-DB-Reader-php/issues",
|
||||||
|
"source": "https://github.com/maxmind/MaxMind-DB-Reader-php/tree/v1.12.0"
|
||||||
|
},
|
||||||
|
"time": "2024-11-14T22:43:47+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "maxmind/web-service-common",
|
||||||
|
"version": "v0.10.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/maxmind/web-service-common-php.git",
|
||||||
|
"reference": "d7c7c42fc31bff26e0ded73a6e187bcfb193f9c4"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/maxmind/web-service-common-php/zipball/d7c7c42fc31bff26e0ded73a6e187bcfb193f9c4",
|
||||||
|
"reference": "d7c7c42fc31bff26e0ded73a6e187bcfb193f9c4",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"composer/ca-bundle": "^1.0.3",
|
||||||
|
"ext-curl": "*",
|
||||||
|
"ext-json": "*",
|
||||||
|
"php": ">=8.1"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"friendsofphp/php-cs-fixer": "3.*",
|
||||||
|
"phpstan/phpstan": "*",
|
||||||
|
"phpunit/phpunit": "^8.0 || ^9.0",
|
||||||
|
"squizlabs/php_codesniffer": "3.*"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"MaxMind\\Exception\\": "src/Exception",
|
||||||
|
"MaxMind\\WebService\\": "src/WebService"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"Apache-2.0"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Gregory Oschwald",
|
||||||
|
"email": "goschwald@maxmind.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Internal MaxMind Web Service API",
|
||||||
|
"homepage": "https://github.com/maxmind/web-service-common-php",
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/maxmind/web-service-common-php/issues",
|
||||||
|
"source": "https://github.com/maxmind/web-service-common-php/tree/v0.10.0"
|
||||||
|
},
|
||||||
|
"time": "2024-11-14T23:14:52+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "nikic/fast-route",
|
"name": "nikic/fast-route",
|
||||||
"version": "v1.3.0",
|
"version": "v1.3.0",
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
<?php
|
<?php
|
||||||
/* Smarty version 5.4.2, created on 2024-12-17 20:54:57
|
/* Smarty version 5.4.2, created on 2024-12-18 17:31:55
|
||||||
from 'file:index.tpl' */
|
from 'file:index.tpl' */
|
||||||
|
|
||||||
/* @var \Smarty\Template $_smarty_tpl */
|
/* @var \Smarty\Template $_smarty_tpl */
|
||||||
if ($_smarty_tpl->getCompiled()->isFresh($_smarty_tpl, array (
|
if ($_smarty_tpl->getCompiled()->isFresh($_smarty_tpl, array (
|
||||||
'version' => '5.4.2',
|
'version' => '5.4.2',
|
||||||
'unifunc' => 'content_6761e5219d7cf3_55254235',
|
'unifunc' => 'content_6763070bd6f6f3_73946052',
|
||||||
'has_nocache_code' => false,
|
'has_nocache_code' => false,
|
||||||
'file_dependency' =>
|
'file_dependency' =>
|
||||||
array (
|
array (
|
||||||
'affb24851ed623b62affa076808377b28b01c478' =>
|
'affb24851ed623b62affa076808377b28b01c478' =>
|
||||||
array (
|
array (
|
||||||
0 => 'index.tpl',
|
0 => 'index.tpl',
|
||||||
1 => 1734468879,
|
1 => 1734543111,
|
||||||
2 => 'file',
|
2 => 'file',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -20,7 +20,7 @@ if ($_smarty_tpl->getCompiled()->isFresh($_smarty_tpl, array (
|
|||||||
array (
|
array (
|
||||||
),
|
),
|
||||||
))) {
|
))) {
|
||||||
function content_6761e5219d7cf3_55254235 (\Smarty\Template $_smarty_tpl) {
|
function content_6763070bd6f6f3_73946052 (\Smarty\Template $_smarty_tpl) {
|
||||||
$_smarty_current_dir = '/home/l/public_html/xbotcontrol/smarty/template';
|
$_smarty_current_dir = '/home/l/public_html/xbotcontrol/smarty/template';
|
||||||
?><!DOCTYPE html>
|
?><!DOCTYPE html>
|
||||||
|
|
||||||
@@ -76,10 +76,12 @@ $_smarty_current_dir = '/home/l/public_html/xbotcontrol/smarty/template';
|
|||||||
<a class="btn text-light" onclick="initializeTable('latest_requests');">Latest</a>
|
<a class="btn text-light" onclick="initializeTable('latest_requests');">Latest</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="btn text-light" onclick="initializeTable('count_requests_by_ip');">Top by IP</a>
|
<a class="btn text-light" onclick="initializeTable('count_requests_by_ip');">Top by
|
||||||
|
IP</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="btn text-light" onclick="initializeTable('count_requests_by_ua');">Top by UA</a>
|
<a class="btn text-light" onclick="initializeTable('count_requests_by_ua');">Top by
|
||||||
|
UA</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="btn text-light" onclick="initializeTable('top_ip_ua_path');">IP+UA+Path</a>
|
<a class="btn text-light" onclick="initializeTable('top_ip_ua_path');">IP+UA+Path</a>
|
||||||
@@ -138,7 +140,7 @@ $_smarty_current_dir = '/home/l/public_html/xbotcontrol/smarty/template';
|
|||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<div class="input-group-text">From</div>
|
<div class="input-group-text">From</div>
|
||||||
|
|
||||||
<input type="datetime-local" id="date-from" name="date-from" class="form-control mr-3" >
|
<input type="datetime-local" id="date-from" name="date-from" class="form-control mr-3">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
@@ -297,6 +299,70 @@ $_smarty_current_dir = '/home/l/public_html/xbotcontrol/smarty/template';
|
|||||||
}
|
}
|
||||||
<?php echo '</script'; ?>
|
<?php echo '</script'; ?>
|
||||||
>
|
>
|
||||||
|
|
||||||
|
<?php echo '<script'; ?>
|
||||||
|
>
|
||||||
|
function ipFormatter(value) {
|
||||||
|
return `<span class="ip-address" data-ip="${value}">${value}</span>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('mouseover', async (event) => {
|
||||||
|
const target = event.target;
|
||||||
|
if (target.classList.contains('ip-address')) {
|
||||||
|
const ipAddress = target.getAttribute('data-ip');
|
||||||
|
const popupId = `popup-${ipAddress.replace(/\./g, '-')}`;
|
||||||
|
let popup = document.getElementById(popupId);
|
||||||
|
|
||||||
|
if (!popup) {
|
||||||
|
popup = document.createElement('div');
|
||||||
|
popup.id = popupId;
|
||||||
|
popup.style.position = 'absolute';
|
||||||
|
popup.style.background = '#f9f9f9';
|
||||||
|
popup.style.border = '1px solid #ccc';
|
||||||
|
popup.style.padding = '10px';
|
||||||
|
popup.style.borderRadius = '5px';
|
||||||
|
popup.style.boxShadow = '0 0 10px rgba(0, 0, 0, 0.2)';
|
||||||
|
popup.style.zIndex = '1000';
|
||||||
|
popup.style.whiteSpace = 'nowrap';
|
||||||
|
popup.style.display = 'none';
|
||||||
|
document.body.appendChild(popup);
|
||||||
|
|
||||||
|
fetch(location.pathname + `/api/ipinfo/${ipAddress}`)
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((data) => {
|
||||||
|
const location = data.geo.continent?.names?.en + ' > ' + data.geo.country
|
||||||
|
?.names?.en + ' > ' + data.geo.city?.names?.en || 'Unknown';
|
||||||
|
const reverseDns = data.reverse_dns || 'N/A';
|
||||||
|
popup.innerHTML = `
|
||||||
|
<strong>Location:</strong> ${location}<br>
|
||||||
|
<strong>Reverse DNS:</strong> ${reverseDns}
|
||||||
|
`;
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
popup.innerHTML = 'Error fetching data.';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
popup.style.display = 'block';
|
||||||
|
popup.style.left = `${event.pageX + 10}px`;
|
||||||
|
popup.style.top = `${event.pageY + 10}px`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener('mouseout', (event) => {
|
||||||
|
const target = event.target;
|
||||||
|
if (target.classList.contains('ip-address')) {
|
||||||
|
const ipAddress = target.getAttribute('data-ip');
|
||||||
|
const popupId = `popup-${ipAddress.replace(/\./g, '-')}`;
|
||||||
|
const popup = document.getElementById(popupId);
|
||||||
|
if (popup) {
|
||||||
|
popup.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
<?php echo '</script'; ?>
|
||||||
|
>
|
||||||
|
|
||||||
<footer class="centro-blue text-white text-center py-3">
|
<footer class="centro-blue text-white text-center py-3">
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<div class="container text-center centro-blue text-light">
|
<div class="container text-center centro-blue text-light">
|
||||||
|
|||||||
@@ -42,10 +42,12 @@
|
|||||||
<a class="btn text-light" onclick="initializeTable('latest_requests');">Latest</a>
|
<a class="btn text-light" onclick="initializeTable('latest_requests');">Latest</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="btn text-light" onclick="initializeTable('count_requests_by_ip');">Top by IP</a>
|
<a class="btn text-light" onclick="initializeTable('count_requests_by_ip');">Top by
|
||||||
|
IP</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="btn text-light" onclick="initializeTable('count_requests_by_ua');">Top by UA</a>
|
<a class="btn text-light" onclick="initializeTable('count_requests_by_ua');">Top by
|
||||||
|
UA</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="btn text-light" onclick="initializeTable('top_ip_ua_path');">IP+UA+Path</a>
|
<a class="btn text-light" onclick="initializeTable('top_ip_ua_path');">IP+UA+Path</a>
|
||||||
@@ -104,7 +106,7 @@
|
|||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<div class="input-group-text">From</div>
|
<div class="input-group-text">From</div>
|
||||||
|
|
||||||
<input type="datetime-local" id="date-from" name="date-from" class="form-control mr-3" >
|
<input type="datetime-local" id="date-from" name="date-from" class="form-control mr-3">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
@@ -258,6 +260,68 @@
|
|||||||
{/if}
|
{/if}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
{literal}
|
||||||
|
<script>
|
||||||
|
function ipFormatter(value) {
|
||||||
|
return `<span class="ip-address" data-ip="${value}">${value}</span>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('mouseover', async (event) => {
|
||||||
|
const target = event.target;
|
||||||
|
if (target.classList.contains('ip-address')) {
|
||||||
|
const ipAddress = target.getAttribute('data-ip');
|
||||||
|
const popupId = `popup-${ipAddress.replace(/\./g, '-')}`;
|
||||||
|
let popup = document.getElementById(popupId);
|
||||||
|
|
||||||
|
if (!popup) {
|
||||||
|
popup = document.createElement('div');
|
||||||
|
popup.id = popupId;
|
||||||
|
popup.style.position = 'absolute';
|
||||||
|
popup.style.background = '#f9f9f9';
|
||||||
|
popup.style.border = '1px solid #ccc';
|
||||||
|
popup.style.padding = '10px';
|
||||||
|
popup.style.borderRadius = '5px';
|
||||||
|
popup.style.boxShadow = '0 0 10px rgba(0, 0, 0, 0.2)';
|
||||||
|
popup.style.zIndex = '1000';
|
||||||
|
popup.style.whiteSpace = 'nowrap';
|
||||||
|
popup.style.display = 'none';
|
||||||
|
document.body.appendChild(popup);
|
||||||
|
|
||||||
|
fetch(location.pathname + `/api/ipinfo/${ipAddress}`)
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((data) => {
|
||||||
|
const location = data.geo.continent?.names?.en + ' > ' + data.geo.country
|
||||||
|
?.names?.en + ' > ' + data.geo.city?.names?.en || 'Unknown';
|
||||||
|
const reverseDns = data.reverse_dns || 'N/A';
|
||||||
|
popup.innerHTML = `
|
||||||
|
<strong>Location:</strong> ${location}<br>
|
||||||
|
<strong>Reverse DNS:</strong> ${reverseDns}
|
||||||
|
`;
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
popup.innerHTML = 'Error fetching data.';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
popup.style.display = 'block';
|
||||||
|
popup.style.left = `${event.pageX + 10}px`;
|
||||||
|
popup.style.top = `${event.pageY + 10}px`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener('mouseout', (event) => {
|
||||||
|
const target = event.target;
|
||||||
|
if (target.classList.contains('ip-address')) {
|
||||||
|
const ipAddress = target.getAttribute('data-ip');
|
||||||
|
const popupId = `popup-${ipAddress.replace(/\./g, '-')}`;
|
||||||
|
const popup = document.getElementById(popupId);
|
||||||
|
if (popup) {
|
||||||
|
popup.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{/literal}
|
||||||
<footer class="centro-blue text-white text-center py-3">
|
<footer class="centro-blue text-white text-center py-3">
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<div class="container text-center centro-blue text-light">
|
<div class="container text-center centro-blue text-light">
|
||||||
|
|||||||
25
src/Classes/GeoIp.php
Normal file
25
src/Classes/GeoIp.php
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace XBotControl\Classes;
|
||||||
|
|
||||||
|
use React\Promise\PromiseInterface;
|
||||||
|
use React\Promise\Promise;
|
||||||
|
|
||||||
|
class GeoIp
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public static function get(string $ipAddress): PromiseInterface
|
||||||
|
{
|
||||||
|
return new Promise(function ($resolve) use ($ipAddress) {
|
||||||
|
$reader = \XBotControl\Config::getinstance()->geoipreader;
|
||||||
|
if ($reader) {
|
||||||
|
$resolve($reader->get($ipAddress));
|
||||||
|
} else {
|
||||||
|
$resolve([]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace XBotControl;
|
namespace XBotControl\Classes;
|
||||||
|
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Clue\React\SQLite\DatabaseInterface;
|
use Clue\React\SQLite\DatabaseInterface;
|
||||||
@@ -10,7 +10,7 @@ use Clue\React\SQLite\Result;
|
|||||||
use React\Promise\PromiseInterface;
|
use React\Promise\PromiseInterface;
|
||||||
use React\Promise\Promise;
|
use React\Promise\Promise;
|
||||||
|
|
||||||
class IPMatch
|
class IPTools
|
||||||
|
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@@ -184,4 +184,90 @@ class IPMatch
|
|||||||
$resolve(false); // Resolve with false if no matches are found
|
$resolve(false); // Resolve with false if no matches are found
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static function checkIfIpBelongsToNetwork(string $ip): PromiseInterface
|
||||||
|
{
|
||||||
|
return self::detectIpVersion($ip)->then(function ($ipVersion) use ($ip) {
|
||||||
|
return self::whitelistRetrieve($ip, $ipVersion)->then(function ($networks) use ($ip, $ipVersion) {
|
||||||
|
if ($ipVersion === 4) {
|
||||||
|
return self::compareIpv4($ip, $networks);
|
||||||
|
} else {
|
||||||
|
return self::compareIpv6($ip, $networks);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function detectIpVersion(string $ip): PromiseInterface
|
||||||
|
{
|
||||||
|
$deferred = new Deferred();
|
||||||
|
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
|
||||||
|
$deferred->resolve(4);
|
||||||
|
} elseif (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
|
||||||
|
$deferred->resolve(6);
|
||||||
|
} else {
|
||||||
|
$deferred->reject("Invalid IP address");
|
||||||
|
}
|
||||||
|
return $deferred->promise();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function whitelistRetrieve(string $ip, int $ipVersion, string $source = '%'): PromiseInterface
|
||||||
|
{
|
||||||
|
$deferred = new Deferred();
|
||||||
|
|
||||||
|
$pdo = new \PDO("mysql:host=localhost;dbname=your_database_name", "username", "password");
|
||||||
|
$sql = "SELECT data FROM networkwhitelist WHERE v = :version";
|
||||||
|
$stmt = $pdo->prepare($sql);
|
||||||
|
$stmt->bindParam(':version', $ipVersion, \PDO::PARAM_INT);
|
||||||
|
$stmt->execute();
|
||||||
|
|
||||||
|
$networks = $stmt->fetchAll(\PDO::FETCH_COLUMN);
|
||||||
|
$deferred->resolve($networks);
|
||||||
|
|
||||||
|
return $deferred->promise();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function compareIpv4(string $ip, array $networks): PromiseInterface
|
||||||
|
{
|
||||||
|
$deferred = new Deferred();
|
||||||
|
|
||||||
|
foreach ($networks as $network) {
|
||||||
|
[$networkIp, $mask] = explode('/', $network);
|
||||||
|
$networkLong = ip2long($networkIp);
|
||||||
|
$maskLong = ~((1 << (32 - $mask)) - 1);
|
||||||
|
$ipLong = ip2long($ip);
|
||||||
|
|
||||||
|
if (($ipLong & $maskLong) === ($networkLong & $maskLong)) {
|
||||||
|
$deferred->resolve(true);
|
||||||
|
return $deferred->promise();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$deferred->resolve(false);
|
||||||
|
|
||||||
|
return $deferred->promise();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function compareIpv6(string $ip, array $networks): PromiseInterface
|
||||||
|
{
|
||||||
|
$deferred = new Deferred();
|
||||||
|
|
||||||
|
foreach ($networks as $network) {
|
||||||
|
[$networkIp, $prefixLength] = explode('/', $network);
|
||||||
|
$networkBin = inet_pton($networkIp);
|
||||||
|
$ipBin = inet_pton($ip);
|
||||||
|
$prefixBytes = intval($prefixLength / 8);
|
||||||
|
$remainingBits = $prefixLength % 8;
|
||||||
|
|
||||||
|
if (strncmp($networkBin, $ipBin, $prefixBytes) === 0) {
|
||||||
|
if ($remainingBits === 0 || ord($networkBin[$prefixBytes]) >> (8 - $remainingBits) === ord($ipBin[$prefixBytes]) >> (8 - $remainingBits)) {
|
||||||
|
$deferred->resolve(true);
|
||||||
|
return $deferred->promise();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$deferred->resolve(false);
|
||||||
|
|
||||||
|
return $deferred->promise();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
84
src/Classes/LogReader.php
Normal file
84
src/Classes/LogReader.php
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
function parseLogFile(&$q, $startTime = 0)
|
||||||
|
{
|
||||||
|
$handle = fopen('/home/upw/clients/kpopping/kpopping_access.log', 'r');
|
||||||
|
if ($handle) {
|
||||||
|
while (($line = fgets($handle)) !== false) {
|
||||||
|
$line = trim($line);
|
||||||
|
if (empty($line)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parts = explode('; ', $line);
|
||||||
|
|
||||||
|
$ip = trim($parts[0]);
|
||||||
|
$dateString = substr($parts[1], 0, 20);
|
||||||
|
$timestamp = DateTime::createFromFormat('d/M/Y:H:i:s', $dateString)->getTimestamp();
|
||||||
|
// var_dump( $timestamp);
|
||||||
|
$requestParts = explode(' ', $parts[2]);
|
||||||
|
$path = trim($requestParts[1] ?? '');
|
||||||
|
|
||||||
|
if ($timestamp < $startTime || strlen($ip) < 3 || str_contains($path, '.')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$logEntry = [
|
||||||
|
'method' => $parts[1],
|
||||||
|
'ip' => $ip,
|
||||||
|
'path' => $path,
|
||||||
|
'timestamp' => $timestamp
|
||||||
|
];
|
||||||
|
React\Async\await($q($logEntry));
|
||||||
|
// process($logEntry, $counter);
|
||||||
|
|
||||||
|
}
|
||||||
|
fclose($handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function process($logEntry, &$counter)
|
||||||
|
{
|
||||||
|
$request = new React\Http\Message\ServerRequest(
|
||||||
|
$logEntry['method'],
|
||||||
|
'https://kpopping.com' . $logEntry['path'],
|
||||||
|
[
|
||||||
|
'X-Forwarded-For' => $logEntry['ip'],
|
||||||
|
'Host' => 'kpopping.com',
|
||||||
|
],
|
||||||
|
'',
|
||||||
|
'1.1'
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
return XBotControl\Request::save($request->withAttribute('original_uri', $logEntry['path']), $logEntry['timestamp']);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
\React\Async\await(XBotControl\InitTables::create());
|
||||||
|
|
||||||
|
$q1 = new Clue\React\Mq\Queue(600, null, function ($logEntry) {
|
||||||
|
$request = new React\Http\Message\ServerRequest(
|
||||||
|
'GET',
|
||||||
|
$logEntry['path'],
|
||||||
|
['X-Forwarded-For' => $logEntry['ip']],
|
||||||
|
'',
|
||||||
|
'1.1',
|
||||||
|
);
|
||||||
|
return XBotControl\Request::save($request, $logEntry['timestamp']);;
|
||||||
|
});
|
||||||
|
$q = function ($logEntry) {
|
||||||
|
$request = new React\Http\Message\ServerRequest(
|
||||||
|
'GET',
|
||||||
|
$logEntry['path'],
|
||||||
|
['X-Forwarded-For' => $logEntry['ip']],
|
||||||
|
'',
|
||||||
|
'1.1',
|
||||||
|
);
|
||||||
|
return XBotControl\Request::save($request, $logEntry['timestamp']);;
|
||||||
|
};
|
||||||
|
//parseLogFile($q, 1734379562);
|
||||||
@@ -61,7 +61,7 @@ class Report
|
|||||||
{
|
{
|
||||||
$columnsDefinition = self::generateColumns([
|
$columnsDefinition = self::generateColumns([
|
||||||
["title" => "id", "field" => "id", "visible" => false],
|
["title" => "id", "field" => "id", "visible" => false],
|
||||||
["title" => "ip", "field" => "ip"],
|
["title" => "ip", "field" => "ip", 'formatter'=> 'ipFormatter'],
|
||||||
["title" => "domain", "field" => "domain", "visible" => false],
|
["title" => "domain", "field" => "domain", "visible" => false],
|
||||||
["title" => "path", "field" => "path"],
|
["title" => "path", "field" => "path"],
|
||||||
["title" => "useragent", "field" => "useragent"],
|
["title" => "useragent", "field" => "useragent"],
|
||||||
@@ -97,7 +97,7 @@ class Report
|
|||||||
public static function count_requests_by_ip(ServerRequestInterface $request): PromiseInterface
|
public static function count_requests_by_ip(ServerRequestInterface $request): PromiseInterface
|
||||||
{
|
{
|
||||||
$columnsDefinition = self::generateColumns([
|
$columnsDefinition = self::generateColumns([
|
||||||
["title" => "ip", "field" => "ip_address"],
|
["title" => "ip", "field" => "ip_address", 'formatter'=> 'ipFormatter'],
|
||||||
["title" => "request_count", "field" => "request_count"],
|
["title" => "request_count", "field" => "request_count"],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -157,7 +157,7 @@ class Report
|
|||||||
public static function top_ip_ua_path(ServerRequestInterface $request): PromiseInterface
|
public static function top_ip_ua_path(ServerRequestInterface $request): PromiseInterface
|
||||||
{
|
{
|
||||||
$columnsDefinition = self::generateColumns([
|
$columnsDefinition = self::generateColumns([
|
||||||
["title" => "ip", "field" => "ip"],
|
["title" => "ip", "field" => "ip", 'formatter'=> 'ipFormatter'],
|
||||||
["title" => "useragent", "field" => "user_agent"],
|
["title" => "useragent", "field" => "user_agent"],
|
||||||
["title" => "path", "field" => "path"],
|
["title" => "path", "field" => "path"],
|
||||||
["title" => "count", "field" => "count"],
|
["title" => "count", "field" => "count"],
|
||||||
@@ -192,7 +192,7 @@ class Report
|
|||||||
public static function top_ip_by_load(ServerRequestInterface $request): PromiseInterface
|
public static function top_ip_by_load(ServerRequestInterface $request): PromiseInterface
|
||||||
{
|
{
|
||||||
$columnsDefinition = self::generateColumns([
|
$columnsDefinition = self::generateColumns([
|
||||||
["title" => "ip", "field" => "data"],
|
["title" => "ip", "field" => "data", 'formatter'=> 'ipFormatter'],
|
||||||
["title" => "avg_load", "field" => "avg_load"],
|
["title" => "avg_load", "field" => "avg_load"],
|
||||||
["title" => "request_count", "field" => "request_count"],
|
["title" => "request_count", "field" => "request_count"],
|
||||||
]);
|
]);
|
||||||
@@ -229,7 +229,7 @@ class Report
|
|||||||
public static function top_ip_by_rps(ServerRequestInterface $request): PromiseInterface
|
public static function top_ip_by_rps(ServerRequestInterface $request): PromiseInterface
|
||||||
{
|
{
|
||||||
$columnsDefinition = self::generateColumns([
|
$columnsDefinition = self::generateColumns([
|
||||||
["title" => "ip", "field" => "ip_address"],
|
["title" => "ip", "field" => "ip_address", 'formatter'=> 'ipFormatter'],
|
||||||
["title" => "avg_request_per_second", "field" => "avg_request_per_second"],
|
["title" => "avg_request_per_second", "field" => "avg_request_per_second"],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
33
src/Classes/ReverseDNS.php
Normal file
33
src/Classes/ReverseDNS.php
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace XBotControl\Classes;
|
||||||
|
use React\Promise\PromiseInterface;
|
||||||
|
|
||||||
|
class ReverseDNS
|
||||||
|
{
|
||||||
|
|
||||||
|
public static function resolve($ip): PromiseInterface
|
||||||
|
{
|
||||||
|
$reverseName = self::getReverseName($ip);
|
||||||
|
return \XBotControl\Config::getInstance()->dnsResolver->resolveAll($reverseName, \React\Dns\Model\Message::TYPE_PTR)->then(function ($ips) {
|
||||||
|
return $ips;
|
||||||
|
}, function () use ($ip){
|
||||||
|
return $ip;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function getReverseName($ip)
|
||||||
|
{
|
||||||
|
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
|
||||||
|
return implode('.', array_reverse(explode('.', $ip))) . '.in-addr.arpa';
|
||||||
|
} elseif (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
|
||||||
|
$unpackedIp = unpack('H*', inet_pton($ip))[1];
|
||||||
|
$reverseIp = implode('.', array_reverse(str_split($unpackedIp))) . '.ip6.arpa';
|
||||||
|
return $reverseIp;
|
||||||
|
} else {
|
||||||
|
return $ip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace XBotControl;
|
namespace XBotControl;
|
||||||
|
|
||||||
|
use MaxMind\Db\Reader;
|
||||||
|
|
||||||
class Config
|
class Config
|
||||||
{
|
{
|
||||||
@@ -14,8 +15,10 @@ class Config
|
|||||||
protected static $instance;
|
protected static $instance;
|
||||||
public $db;
|
public $db;
|
||||||
public $smarty;
|
public $smarty;
|
||||||
|
public $geoipreader;
|
||||||
|
public $dnsResolver;
|
||||||
|
|
||||||
public function __construct()
|
private function __construct()
|
||||||
{
|
{
|
||||||
|
|
||||||
$this->smarty = new \Smarty\Smarty();
|
$this->smarty = new \Smarty\Smarty();
|
||||||
@@ -28,7 +31,15 @@ class Config
|
|||||||
'baseURI' => $_ENV['BASEURI'],
|
'baseURI' => $_ENV['BASEURI'],
|
||||||
]);
|
]);
|
||||||
$this->smarty->compile_check = 1;
|
$this->smarty->compile_check = 1;
|
||||||
/* $this->db = (new \Clue\React\SQLite\Factory())->openLazy($_ENV['APP_DIR'] . '/bots.db');
|
if (isset($_ENV['GEOIP_DB_FILE_PATH'])) {
|
||||||
|
$this->geoipreader = new Reader($_ENV['APP_DIR'].'/'.$_ENV['GEOIP_DB_FILE']);
|
||||||
|
}
|
||||||
|
$dnsConfig = \React\Dns\Config\Config::loadSystemConfigBlocking();
|
||||||
|
$dnsConfig->nameservers[] = '8.8.8.8';
|
||||||
|
$dnsConfig->nameservers[] = '8.8.4.4';
|
||||||
|
$this->dnsResolver = (new \React\Dns\Resolver\Factory())->createCached($dnsConfig);
|
||||||
|
|
||||||
|
/* $this->db = (new \Clue\React\SQLite\Factory())->openLazy($_ENV['APP_DIR'] . '/bots.db');
|
||||||
'uaCache' => new React\Cache\ArrayCache(1000),
|
'uaCache' => new React\Cache\ArrayCache(1000),
|
||||||
'ipCache' => new React\Cache\ArrayCache(1000),
|
'ipCache' => new React\Cache\ArrayCache(1000),
|
||||||
'headerCache' => new React\Cache\ArrayCache(1000),
|
'headerCache' => new React\Cache\ArrayCache(1000),
|
||||||
@@ -73,6 +84,4 @@ class Config
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,18 @@ class APIController
|
|||||||
return call_user_func([\XBotControl\Classes\Report::class, $request->getAttribute('resource')], $request)->then(function ($result) {
|
return call_user_func([\XBotControl\Classes\Report::class, $request->getAttribute('resource')], $request)->then(function ($result) {
|
||||||
return \React\Http\Message\Response::json($result);
|
return \React\Http\Message\Response::json($result);
|
||||||
});
|
});
|
||||||
|
case 'ipinfo':
|
||||||
|
$ipAddress = $request->getAttribute('resource');
|
||||||
|
return call_user_func([\XBotControl\Classes\GeoIp::class, 'get'], $ipAddress)
|
||||||
|
->then(function ($geoResult) use ($ipAddress) {
|
||||||
|
return \XBotControl\Classes\ReverseDNS::resolve($ipAddress) // Replace SomeClass with the correct class name
|
||||||
|
->then(function ($reverseDns) use ($geoResult) {
|
||||||
|
return \React\Http\Message\Response::json([
|
||||||
|
'geo' => $geoResult,
|
||||||
|
'reverse_dns' => $reverseDns
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
default:
|
default:
|
||||||
return \React\Http\Message\Response::json(
|
return \React\Http\Message\Response::json(
|
||||||
['empty_response']
|
['empty_response']
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class InitTables
|
|||||||
})->then(function () use ($db) {
|
})->then(function () use ($db) {
|
||||||
return $db->exec('CREATE TABLE IF NOT EXISTS headers ( data TEXT UNIQUE NOT NULL) STRICT ;');
|
return $db->exec('CREATE TABLE IF NOT EXISTS headers ( data TEXT UNIQUE NOT NULL) STRICT ;');
|
||||||
})->then(function () use ($db) {
|
})->then(function () use ($db) {
|
||||||
return $db->exec("CREATE TABLE IF NOT EXISTS networkwhitelist ( data TEXT UNIQUE NOT NULL CHECK (data LIKE '%/%'), source TEXT NULL , CONSTRAINT valid_network CHECK ( data LIKE '%.%/%' OR data LIKE '%:%/%' )) STRICT ;");
|
return $db->exec("CREATE TABLE IF NOT EXISTS networkwhitelist ( data TEXT UNIQUE NOT NULL CHECK (data LIKE '%/%'), source TEXT NULL , v INT NOT NULL , CONSTRAINT valid_network CHECK ( data LIKE '%.%/%' OR data LIKE '%:%/%' )) STRICT ;");
|
||||||
})->then(function () use ($db) {
|
})->then(function () use ($db) {
|
||||||
return $db->exec('CREATE TABLE IF NOT EXISTS request ( id_ip INTEGER NOT NULL, id_method INTEGER NOT NULL, id_domain INTEGER NOT NULL, id_path INTEGER NOT NULL, id_useragent INTEGER NOT NULL, id_headers INTEGER NOT NULL, timestamp INTEGER NOT NULL, FOREIGN KEY (id_ip) REFERENCES ip(rowid), FOREIGN KEY (id_domain) REFERENCES domain(rowid), FOREIGN KEY (id_path) REFERENCES path(rowid), FOREIGN KEY (id_useragent) REFERENCES useragent(rowid), FOREIGN KEY (id_headers) REFERENCES headers(rowid) ) STRICT ;');
|
return $db->exec('CREATE TABLE IF NOT EXISTS request ( id_ip INTEGER NOT NULL, id_method INTEGER NOT NULL, id_domain INTEGER NOT NULL, id_path INTEGER NOT NULL, id_useragent INTEGER NOT NULL, id_headers INTEGER NOT NULL, timestamp INTEGER NOT NULL, FOREIGN KEY (id_ip) REFERENCES ip(rowid), FOREIGN KEY (id_domain) REFERENCES domain(rowid), FOREIGN KEY (id_path) REFERENCES path(rowid), FOREIGN KEY (id_useragent) REFERENCES useragent(rowid), FOREIGN KEY (id_headers) REFERENCES headers(rowid) ) STRICT ;');
|
||||||
})->then(function () use ($db) {
|
})->then(function () use ($db) {
|
||||||
|
|||||||
Reference in New Issue
Block a user