Added DevicesManager
This commit is contained in:
parent
6215c69595
commit
fcbad59a59
|
@ -0,0 +1,26 @@
|
|||
create table devices
|
||||
(
|
||||
fingerprint varchar(126) not null comment 'The fingerprint of the device',
|
||||
user_agent varchar(255) not null comment 'The full raw user agent string of the device',
|
||||
os_family varchar(255) null comment 'The Operating System family of the user agent',
|
||||
os_version varchar(126) null comment 'The version of the operating system',
|
||||
device_family varchar(255) null comment 'The family of the device',
|
||||
device_brand varchar(255) null comment 'The brand of the device',
|
||||
device_model varchar(255) null comment 'The model of the device',
|
||||
browser_family varchar(255) null comment 'The family of the web browser that''s being used',
|
||||
browser_version varchar(255) null comment 'The version of the browser that''s being used',
|
||||
mobile_browser bool null comment 'Indicates if the browser is on a mobile platform',
|
||||
mobile_device bool null comment 'Indicates if the device is a mobile device',
|
||||
last_seen_timestamp int null comment 'The Unix Timestamp for when this device was last seen',
|
||||
created_timestamp int null comment 'The Unix Timestamp for when this record was first registered into the database',
|
||||
constraint devices_pk
|
||||
primary key (fingerprint)
|
||||
)
|
||||
comment 'Table for housing known devices and their properties';
|
||||
|
||||
create unique index devices_fingerprint_uindex
|
||||
on devices (fingerprint);
|
||||
|
||||
create unique index devices_user_agent_uindex
|
||||
on devices (user_agent);
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
create table if not exists known_devices
|
||||
(
|
||||
ip_address varchar(126) null comment 'The IP address of the host',
|
||||
ip_version int null comment 'The version of the IP Address',
|
||||
device_fingerprint varchar(126) null comment 'The fingerprint of the device',
|
||||
properties blob null comment 'ZiProto encoded blob of properties associated with this device',
|
||||
last_seen_timestamp int null comment 'The Unix Timestamp for when this device and host was last seen',
|
||||
created_timestamp int null comment 'The Unix Timestamp for when this record was first registered',
|
||||
constraint known_devices_ip_address_device_fingerprint_uindex
|
||||
unique (ip_address, device_fingerprint),
|
||||
constraint known_devices_devices_fingerprint_fk
|
||||
foreign key (device_fingerprint) references devices (fingerprint),
|
||||
constraint known_devices_known_hosts_ip_address_fk
|
||||
foreign key (ip_address) references known_hosts (ip_address)
|
||||
)
|
||||
comment 'A table for housing the relationship between a host and a device to detect if a device is using multiple hosts';
|
||||
|
||||
create index known_devices_device_fingerprint_index
|
||||
on known_devices (device_fingerprint);
|
||||
|
||||
create index known_devices_ip_address_index
|
||||
on known_devices (ip_address);
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
create table if not exists known_hosts
|
||||
(
|
||||
ip_address varchar(126) not null comment 'The IP address of the known host'
|
||||
primary key,
|
||||
properties blob null comment 'ZiProto encoded blob for this hosts properties',
|
||||
last_seen_timestamp int null comment 'The Unix Timestamp for when this host was last seen',
|
||||
created_timestamp int null comment 'The Unix Timestamp for when this host was first seen',
|
||||
constraint known_hosts_ip_address_uindex
|
||||
unique (ip_address)
|
||||
)
|
||||
comment 'Table for housing known hosts and their properties';
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace khm\Abstracts;
|
||||
|
||||
abstract class AbstractClient
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
abstract public function toString(): string;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
namespace khm\Abstracts;
|
||||
|
||||
abstract class AbstractParser
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $regexes = [];
|
||||
|
||||
public function __construct(array $regexes)
|
||||
{
|
||||
$this->regexes = $regexes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $regexes
|
||||
* @param string $userAgent
|
||||
* @return array
|
||||
*/
|
||||
protected static function tryMatch(array $regexes, string $userAgent): array
|
||||
{
|
||||
foreach ($regexes as $regex) {
|
||||
if (preg_match($regex['regex'], $userAgent, $matches)) {
|
||||
|
||||
$defaults = [
|
||||
1 => 'Other',
|
||||
2 => null,
|
||||
3 => null,
|
||||
4 => null,
|
||||
5 => null,
|
||||
];
|
||||
|
||||
return [$regex, $matches + $defaults];
|
||||
}
|
||||
}
|
||||
|
||||
return [null, null];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $regex
|
||||
* @param string $key
|
||||
* @param string|null $default
|
||||
* @param array $matches
|
||||
* @return string|null
|
||||
*/
|
||||
protected static function multiReplace(array $regex, string $key, ?string $default, array $matches): ?string
|
||||
{
|
||||
if (!isset($regex[$key])) {
|
||||
return self::emptyStringToNull($default);
|
||||
}
|
||||
|
||||
$replacement = preg_replace_callback(
|
||||
'|\$(?P<key>\d)|',
|
||||
static function ($m) use ($matches) {
|
||||
return $matches[$m['key']] ?? '';
|
||||
},
|
||||
$regex[$key]
|
||||
);
|
||||
|
||||
return self::emptyStringToNull($replacement);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $string
|
||||
* @return string|null
|
||||
*/
|
||||
private static function emptyStringToNull(?string $string): ?string
|
||||
{
|
||||
$string = trim($string ?? '');
|
||||
|
||||
return $string === '' ? null : $string;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace khm\Abstracts;
|
||||
|
||||
abstract class AbstractSoftware extends AbstractClient
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $family = 'Other';
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return $this->family;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace khm\Abstracts;
|
||||
|
||||
use DynamicalWeb\Abstracts\AbstractSoftware;
|
||||
|
||||
abstract class AbstractVersionedSoftware extends AbstractSoftware
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
abstract public function toVersion(): string;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return implode(' ', array_filter([$this->family, $this->toVersion()]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null ...$args
|
||||
* @return string
|
||||
* @noinspection PhpUnused
|
||||
*/
|
||||
protected function formatVersion(?string ...$args): string
|
||||
{
|
||||
return implode('.', array_filter($args, 'is_numeric'));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace khm\Abstracts;
|
||||
|
||||
abstract class HostFlags
|
||||
{
|
||||
/**
|
||||
* Indicates that this IP address has a history of reported
|
||||
*/
|
||||
const BadUser = 'BAD_USER';
|
||||
|
||||
/**
|
||||
* Indicates that the IP address is a part of the Tor network acting as a relay
|
||||
*/
|
||||
const TorRelay = 'TOR_RELAY';
|
||||
|
||||
/**
|
||||
* Indicates that the IP address is an exit node
|
||||
*/
|
||||
const TorExit = 'TOR_EXIT';
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace khm\Abstracts\SearchMethods;
|
||||
|
||||
abstract class DeviceSearchMethod
|
||||
{
|
||||
const ByFingerprint = 'fingerprint';
|
||||
|
||||
const ByUserAgent = 'user_agent';
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
<?php
|
||||
|
||||
namespace khm\Classes;
|
||||
|
||||
use khm\Classes\UserAgentParser\Parser;
|
||||
use khm\Exceptions\NoUserAgentProvidedException;
|
||||
use khm\Objects\Device;
|
||||
|
||||
class DeviceDetection
|
||||
{
|
||||
/**
|
||||
* Detects the client's device if applicable
|
||||
*
|
||||
* @return Device
|
||||
* @throws NoUserAgentProvidedException
|
||||
*/
|
||||
public static function detectDevice(): Device
|
||||
{
|
||||
if(isset($_SERVER['HTTP_USER_AGENT']) == false)
|
||||
throw new NoUserAgentProvidedException('Cannot detect the device because no user agent was provided');
|
||||
|
||||
$parser = new Parser();
|
||||
$parsed_ua = $parser->parse($_SERVER['HTTP_USER_AGENT']);
|
||||
|
||||
$MobileBrowserRegex = RegexLoader::getMobile1();
|
||||
$MobileDeviceRegex = RegexLoader::getMobile2();
|
||||
|
||||
$Device = new Device();
|
||||
$Device->Fingerprint = hash('sha1', $_SERVER['HTTP_USER_AGENT']);
|
||||
$Device->UserAgent = $_SERVER['HTTP_USER_AGENT'];
|
||||
$Device->OperatingSystemFamily = ($parsed_ua->os->family == null ? null : $parsed_ua->os->family);
|
||||
$Device->OperatingSystemVersion = ($parsed_ua->os->toVersion() == null ? null : $parsed_ua->os->toVersion());
|
||||
$Device->DeviceFamily = ($parsed_ua->device->family == null ? null : $parsed_ua->device->family);
|
||||
$Device->DeviceBrand = ($parsed_ua->device->brand == null ? null : $parsed_ua->device->brand);
|
||||
$Device->DeviceModel = ($parsed_ua->device->model == null ? null : $parsed_ua->device->model);
|
||||
$Device->BrowserFamily = ($parsed_ua->ua->family == null ? null : $parsed_ua->ua->family);
|
||||
$Device->BrowserVersion = ($parsed_ua->ua->toVersion() == null ? null : $parsed_ua->ua->toVersion());
|
||||
$Device->MobileBrowser = (bool)preg_match($MobileBrowserRegex, $_SERVER['HTTP_USER_AGENT']);
|
||||
$Device->MobileDevice = (bool)preg_match($MobileDeviceRegex, $_SERVER['HTTP_USER_AGENT']);
|
||||
|
||||
return $Device;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the IP address of the client
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getClientIP(): string
|
||||
{
|
||||
if(isset($_SERVER['HTTP_CF_CONNECTING_IP']))
|
||||
{
|
||||
return $_SERVER['HTTP_CF_CONNECTING_IP'];
|
||||
}
|
||||
|
||||
if(isset($_SERVER['HTTP_CLIENT_IP']))
|
||||
{
|
||||
return $_SERVER['HTTP_CLIENT_IP'];
|
||||
}
|
||||
|
||||
if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
|
||||
{
|
||||
return $_SERVER['HTTP_X_FORWARDED_FOR'];
|
||||
}
|
||||
|
||||
if(isset($_SERVER['HTTP_X_FORWARDED']))
|
||||
{
|
||||
return $_SERVER['HTTP_X_FORWARDED'];
|
||||
}
|
||||
|
||||
if(isset($_SERVER['HTTP_FORWARDED_FOR']))
|
||||
{
|
||||
return $_SERVER['HTTP_FORWARDED_FOR'];
|
||||
}
|
||||
|
||||
if(isset($_SERVER['HTTP_FORWARDED']))
|
||||
{
|
||||
return $_SERVER['HTTP_FORWARDED'];
|
||||
}
|
||||
|
||||
if(isset($_SERVER['REMOTE_ADDR']))
|
||||
{
|
||||
return $_SERVER['REMOTE_ADDR'];
|
||||
}
|
||||
|
||||
if(getenv('HTTP_CLIENT_IP') !== False)
|
||||
{
|
||||
return getenv('HTTP_CLIENT_IP');
|
||||
}
|
||||
|
||||
if(getenv('HTTP_X_FORWARDED_FOR'))
|
||||
{
|
||||
return getenv('HTTP_X_FORWARDED_FOR');
|
||||
}
|
||||
|
||||
if(getenv('HTTP_X_FORWARDED'))
|
||||
{
|
||||
return getenv('HTTP_X_FORWARDED');
|
||||
}
|
||||
|
||||
if(getenv('HTTP_FORWARDED_FOR'))
|
||||
{
|
||||
return getenv('HTTP_FORWARDED_FOR');
|
||||
}
|
||||
|
||||
if(getenv('HTTP_FORWARDED'))
|
||||
{
|
||||
return getenv('HTTP_FORWARDED');
|
||||
}
|
||||
|
||||
if(getenv('REMOTE_ADDR'))
|
||||
{
|
||||
return getenv('REMOTE_ADDR');
|
||||
}
|
||||
|
||||
return '127.0.0.1';
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace khm\Classes;
|
||||
|
||||
class RegexLoader
|
||||
{
|
||||
/**
|
||||
* Loads the mobile1.regex file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getMobile1(): string
|
||||
{
|
||||
$path = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'mobile1.regex';
|
||||
return file_get_contents($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the mobile1.regex file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getMobile2(): string
|
||||
{
|
||||
$path = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'mobile2.regex';
|
||||
return file_get_contents($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the regexes.json
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getRegex(): array
|
||||
{
|
||||
$path = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'regexes.json';
|
||||
return json_decode(file_get_contents($path), true);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
namespace khm\Classes;
|
||||
|
||||
use khm\Abstracts\AbstractParser;
|
||||
use khm\Objects\UserAgent;
|
||||
|
||||
class UserAgentParser extends AbstractParser
|
||||
{
|
||||
/**
|
||||
* Attempts to see if the user agent matches a user agents regex
|
||||
* @noinspection PhpStrFunctionsInspection
|
||||
* @noinspection RedundantSuppression
|
||||
*/
|
||||
public function parseUserAgent(string $userAgent, array $jsParseBits = []): UserAgent
|
||||
{
|
||||
$ua = new UserAgent();
|
||||
|
||||
if (isset($jsParseBits['js_user_agent_family']) && $jsParseBits['js_user_agent_family'])
|
||||
{
|
||||
$ua->family = $jsParseBits['js_user_agent_family'];
|
||||
$ua->major = $jsParseBits['js_user_agent_v1'];
|
||||
$ua->minor = $jsParseBits['js_user_agent_v2'];
|
||||
$ua->patch = $jsParseBits['js_user_agent_v3'];
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
[$regex, $matches] = self::tryMatch($this->regexes['user_agent_parsers'], $userAgent);
|
||||
|
||||
if ($matches)
|
||||
{
|
||||
$ua->family = self::multiReplace($regex, 'family_replacement', $matches[1], $matches) ?? $ua->family;
|
||||
$ua->major = self::multiReplace($regex, 'v1_replacement', $matches[2], $matches);
|
||||
$ua->minor = self::multiReplace($regex, 'v2_replacement', $matches[3], $matches);
|
||||
$ua->patch = self::multiReplace($regex, 'v3_replacement', $matches[4], $matches);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($jsParseBits['js_user_agent_string']))
|
||||
{
|
||||
$jsUserAgentString = $jsParseBits['js_user_agent_string'];
|
||||
if (strpos($jsUserAgentString, 'Chrome/') !== false && strpos($userAgent, 'chromeframe') !== false)
|
||||
{
|
||||
$override = $this->parseUserAgent($jsUserAgentString);
|
||||
$family = $ua->family;
|
||||
$ua->family = 'Chrome Frame';
|
||||
|
||||
if ($family !== null && $ua->major !== null)
|
||||
$ua->family .= sprintf(' (%s %s)', $family, $ua->major);
|
||||
|
||||
$ua->major = $override->major;
|
||||
$ua->minor = $override->minor;
|
||||
$ua->patch = $override->patch;
|
||||
}
|
||||
}
|
||||
|
||||
return $ua;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace khm\Classes\UserAgentParser;
|
||||
|
||||
use khm\Abstracts\AbstractParser;
|
||||
use khm\Objects\UserAgentDevice;
|
||||
|
||||
class DeviceParser extends AbstractParser
|
||||
{
|
||||
/**
|
||||
* Attempts to see if the user agent matches a device regex
|
||||
*
|
||||
* @param string $userAgent
|
||||
* @return UserAgentDevice
|
||||
*/
|
||||
public function parseDevice(string $userAgent): UserAgentDevice
|
||||
{
|
||||
$device = new UserAgentDevice();
|
||||
|
||||
[$regex, $matches] = self::tryMatch($this->regexes['device_parsers'], $userAgent);
|
||||
|
||||
if ($matches) {
|
||||
$device->family = self::multiReplace($regex, 'device_replacement', $matches[1], $matches) ?? $device->family;
|
||||
$device->brand = self::multiReplace($regex, 'brand_replacement', null, $matches);
|
||||
$deviceModelDefault = $matches[1] !== 'Other' ? $matches[1] : null;
|
||||
$device->model = self::multiReplace($regex, 'model_replacement', $deviceModelDefault, $matches);
|
||||
}
|
||||
|
||||
return $device;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace khm\Classes\UserAgentParser;
|
||||
|
||||
use khm\Abstracts\AbstractParser;
|
||||
use khm\Objects\UserAgentOperatingSystem;
|
||||
|
||||
class OperatingSystemParser extends AbstractParser
|
||||
{
|
||||
|
||||
/**
|
||||
* Attempts to see if the user agent matches an operating system regex
|
||||
*
|
||||
* @param string $userAgent
|
||||
* @return UserAgentOperatingSystem
|
||||
*/
|
||||
public function parseOperatingSystem(string $userAgent): UserAgentOperatingSystem
|
||||
{
|
||||
$os = new UserAgentOperatingSystem();
|
||||
|
||||
[$regex, $matches] = self::tryMatch($this->regexes['os_parsers'], $userAgent);
|
||||
|
||||
if ($matches) {
|
||||
$os->family = self::multiReplace($regex, 'os_replacement', $matches[1], $matches) ?? $os->family;
|
||||
$os->major = self::multiReplace($regex, 'os_v1_replacement', $matches[2], $matches);
|
||||
$os->minor = self::multiReplace($regex, 'os_v2_replacement', $matches[3], $matches);
|
||||
$os->patch = self::multiReplace($regex, 'os_v3_replacement', $matches[4], $matches);
|
||||
$os->patchMinor = self::multiReplace($regex, 'os_v4_replacement', $matches[5], $matches);
|
||||
}
|
||||
|
||||
return $os;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
namespace khm\Classes\UserAgentParser;
|
||||
|
||||
class Parser extends AbstractParser
|
||||
{
|
||||
/**
|
||||
* @var DeviceParser
|
||||
*/
|
||||
private $deviceParser;
|
||||
|
||||
/**
|
||||
* @var OperatingSystemParser
|
||||
*/
|
||||
private $operatingSystemParser;
|
||||
|
||||
/**
|
||||
* @var UserAgentParser
|
||||
*/
|
||||
private $userAgentParser;
|
||||
|
||||
/**
|
||||
* Start up the parser by importing the data file to $this->regexes
|
||||
* @throws FileNotFoundException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(Utilities::getUserAgentRegexes());
|
||||
$this->deviceParser = new DeviceParser($this->regexes);
|
||||
$this->operatingSystemParser = new OperatingSystemParser($this->regexes);
|
||||
$this->userAgentParser = new UserAgentParser($this->regexes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up some standard variables as well as starts the user agent parsing process
|
||||
*
|
||||
* @param string $userAgent
|
||||
* @param array $jsParseBits
|
||||
* @return UserAgentClient
|
||||
*/
|
||||
public function parse(string $userAgent, array $jsParseBits = []): UserAgentClient
|
||||
{
|
||||
$client = new UserAgentClient($userAgent);
|
||||
|
||||
$client->ua = $this->userAgentParser->parseUserAgent($userAgent, $jsParseBits);
|
||||
$client->os = $this->operatingSystemParser->parseOperatingSystem($userAgent);
|
||||
$client->device = $this->deviceParser->parseDevice($userAgent);
|
||||
|
||||
return $client;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace khm\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use Throwable;
|
||||
|
||||
class DeviceRecordNotFoundException extends Exception
|
||||
{
|
||||
/**
|
||||
* @param $message
|
||||
* @param $code
|
||||
* @param Throwable|null $previous
|
||||
* @noinspection PhpMissingParamTypeInspection
|
||||
*/
|
||||
public function __construct($message = "", $code = 0, Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
$this->message = $message;
|
||||
$this->code = $code;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace khm\Exceptions;
|
||||
|
||||
|
||||
use Exception;
|
||||
use Throwable;
|
||||
|
||||
class InvalidSearchMethodException extends Exception
|
||||
{
|
||||
/**
|
||||
* @param $message
|
||||
* @param $code
|
||||
* @param Throwable|null $previous
|
||||
* @noinspection PhpMissingParamTypeInspection
|
||||
*/
|
||||
public function __construct($message="", $code=0, Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
$this->message = $message;
|
||||
$this->code = $code;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace khm\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use Throwable;
|
||||
|
||||
class NoUserAgentProvidedException extends Exception
|
||||
{
|
||||
/**
|
||||
* @param $message
|
||||
* @param $code
|
||||
* @param Throwable|null $previous
|
||||
* @noinspection PhpMissingParamTypeInspection
|
||||
*/
|
||||
public function __construct($message = "", $code = 0, Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
$this->message = $message;
|
||||
$this->code = $code;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,173 @@
|
|||
<?php
|
||||
|
||||
namespace khm\Managers;
|
||||
|
||||
use khm\Abstracts\SearchMethods\DeviceSearchMethod;
|
||||
use khm\Exceptions\DatabaseException;
|
||||
use khm\Exceptions\DeviceRecordNotFoundException;
|
||||
use khm\Exceptions\InvalidSearchMethodException;
|
||||
use khm\khm;
|
||||
use khm\Objects\Device;
|
||||
use msqg\QueryBuilder;
|
||||
use ZiProto\ZiProto;
|
||||
|
||||
class DevicesManager
|
||||
{
|
||||
/**
|
||||
* @var khm
|
||||
*/
|
||||
private $khm;
|
||||
|
||||
/**
|
||||
* @param khm $khm
|
||||
*/
|
||||
public function __construct(khm $khm)
|
||||
{
|
||||
$this->khm = $khm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a new record into the database
|
||||
*
|
||||
* @param Device $device
|
||||
* @return Device
|
||||
* @throws DatabaseException
|
||||
* @noinspection PhpCastIsUnnecessaryInspection
|
||||
*/
|
||||
public function registerRecord(Device $device): Device
|
||||
{
|
||||
$device->LastSeenTimestamp = time();
|
||||
$device->CreatedTimestamp = time();
|
||||
if($device->Properties == null)
|
||||
$device->Properties = new Device\Properties();
|
||||
|
||||
$Query = QueryBuilder::insert_into('devices', [
|
||||
'fingerprint' => $this->khm->getDatabase()->real_escape_string($device->Fingerprint),
|
||||
'user_agent' => $this->khm->getDatabase()->real_escape_string($device->UserAgent),
|
||||
'os_family' => ($device->OperatingSystemFamily == null ? null : $this->khm->getDatabase()->real_escape_string($device->OperatingSystemFamily)),
|
||||
'os_version' => ($device->OperatingSystemVersion == null ? null : $this->khm->getDatabase()->real_escape_string($device->OperatingSystemVersion)),
|
||||
'device_family' => ($device->DeviceFamily == null ? null : $this->khm->getDatabase()->real_escape_string($device->DeviceFamily)),
|
||||
'device_brand' => ($device->DeviceBrand == null ? null : $this->khm->getDatabase()->real_escape_string($device->DeviceBrand)),
|
||||
'device_model' => ($device->DeviceModel == null ? null : $this->khm->getDatabase()->real_escape_string($device->DeviceModel)),
|
||||
'browser_family' => ($device->BrowserFamily == null ? null : $this->khm->getDatabase()->real_escape_string($device->BrowserFamily)),
|
||||
'browser_version' => ($device->BrowserVersion == null ? null : $this->khm->getDatabase()->real_escape_string($device->BrowserVersion)),
|
||||
'mobile_browser' => ($device->MobileBrowser == null ? null : $this->khm->getDatabase()->real_escape_string($device->MobileBrowser)),
|
||||
'mobile_device' => ($device->MobileDevice == null ? null : $this->khm->getDatabase()->real_escape_string($device->MobileDevice)),
|
||||
'properties' => $this->khm->getDatabase()->real_escape_string(ZiProto::encode($device->Properties->toArray())),
|
||||
'last_seen_timestamp' => (int)$device->LastSeenTimestamp,
|
||||
'created_timestamp' => (int)$device->CreatedTimestamp
|
||||
]);
|
||||
|
||||
$QueryResults = $this->khm->getDatabase()->query($Query);
|
||||
|
||||
if($QueryResults == false)
|
||||
{
|
||||
throw new DatabaseException($Query, $this->khm->getDatabase()->error);
|
||||
}
|
||||
|
||||
return $device;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an existing record from the database
|
||||
*
|
||||
* @throws InvalidSearchMethodException
|
||||
* @throws DeviceRecordNotFoundException
|
||||
* @throws DatabaseException
|
||||
*/
|
||||
public function getRecord(string $search_method, string $value): Device
|
||||
{
|
||||
switch($search_method)
|
||||
{
|
||||
case DeviceSearchMethod::ByFingerprint:
|
||||
case DeviceSearchMethod::ByUserAgent:
|
||||
$search_method = $this->khm->getDatabase()->real_escape_string($search_method);
|
||||
$value = $this->khm->getDatabase()->real_escape_string($value);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new InvalidSearchMethodException('The given search method \'' . $search_method . '\' is not affected');
|
||||
}
|
||||
|
||||
$Query = QueryBuilder::select('devices', [
|
||||
'fingerprint',
|
||||
'user_agent',
|
||||
'os_family',
|
||||
'device_family',
|
||||
'device_brand',
|
||||
'device_model',
|
||||
'browser_family',
|
||||
'browser_version',
|
||||
'mobile_browser',
|
||||
'mobile_device',
|
||||
'properties',
|
||||
'last_seen_timestamp',
|
||||
'created_timestamp'
|
||||
], $search_method, $value);
|
||||
|
||||
$QueryResults = $this->khm->getDatabase()->query($Query);
|
||||
|
||||
if($QueryResults == false)
|
||||
{
|
||||
throw new DatabaseException($Query, $this->khm->getDatabase()->error);
|
||||
}
|
||||
|
||||
$Row = $QueryResults->fetch_array(MYSQLI_ASSOC);
|
||||
|
||||
if ($Row == False)
|
||||
{
|
||||
throw new DeviceRecordNotFoundException('The device record wa was not found');
|
||||
}
|
||||
|
||||
$Row['properties'] = ZiProto::decode($Row['properties']);
|
||||
|
||||
return Device::fromArray($Row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the properties of a device
|
||||
*
|
||||
* @param Device $device
|
||||
* @return void
|
||||
* @throws DatabaseException
|
||||
*/
|
||||
public function updateDeviceProperties(Device $device)
|
||||
{
|
||||
$Query = QueryBuilder::update('devices', [
|
||||
'properties' => $this->khm->getDatabase()->real_escape_string(ZiProto::encode($device->toArray()))
|
||||
], 'fingerprint', $this->khm->getDatabase()->real_escape_string($device->Fingerprint));
|
||||
|
||||
|
||||
$QueryResults = $this->khm->getDatabase()->query($Query);
|
||||
|
||||
if($QueryResults == false)
|
||||
{
|
||||
throw new DatabaseException($Query, $this->khm->getDatabase()->error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the last seen of a device
|
||||
*
|
||||
* @param Device $device
|
||||
* @return void
|
||||
* @throws DatabaseException
|
||||
*/
|
||||
public function updateLastSeen(Device $device): Device
|
||||
{
|
||||
$device->LastSeenTimestamp = time();
|
||||
$Query = QueryBuilder::update('devices', [
|
||||
'last_seen_timestamp' => $device->LastSeenTimestamp
|
||||
], 'fingerprint', $this->khm->getDatabase()->real_escape_string($device->Fingerprint));
|
||||
|
||||
|
||||
$QueryResults = $this->khm->getDatabase()->query($Query);
|
||||
|
||||
if($QueryResults == false)
|
||||
{
|
||||
throw new DatabaseException($Query, $this->khm->getDatabase()->error);
|
||||
}
|
||||
|
||||
return $device;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,188 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace khm\Objects;
|
||||
|
||||
use khm\Objects\Device\Properties;
|
||||
|
||||
class Device
|
||||
{
|
||||
/**
|
||||
* The unique fingerprint for the device
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $Fingerprint;
|
||||
|
||||
/**
|
||||
* The raw user agent string returned by the client
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $UserAgent;
|
||||
|
||||
/**
|
||||
* The detected operating system family
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $OperatingSystemFamily;
|
||||
|
||||
/**
|
||||
* The detected operating system version
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $OperatingSystemVersion;
|
||||
|
||||
/**
|
||||
* The detected device family
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $DeviceFamily;
|
||||
|
||||
/**
|
||||
* The detected device brand
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $DeviceBrand;
|
||||
|
||||
/**
|
||||
* The detected device model
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $DeviceModel;
|
||||
|
||||
/**
|
||||
* The detected version of the browser family
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $BrowserFamily;
|
||||
|
||||
/**
|
||||
* The detected version of the browser
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $BrowserVersion;
|
||||
|
||||
/**
|
||||
* Indicates if the browser is a mobile browser
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $MobileBrowser;
|
||||
|
||||
/**
|
||||
* Indicates if the device is a mobile device
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $MobileDevice;
|
||||
|
||||
/**
|
||||
* Properties associated with this device
|
||||
*
|
||||
* @var Properties
|
||||
*/
|
||||
public $Properties;
|
||||
|
||||
/**
|
||||
* The Unix Timestamp for when this device was last seen
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $LastSeenTimestamp;
|
||||
|
||||
/**
|
||||
* The Unix Timestamp for when this record was first created
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $CreatedTimestamp;
|
||||
|
||||
/**
|
||||
* Returns an array representation of the object
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'fingerprint' => $this->Fingerprint,
|
||||
'user_agent' => $this->UserAgent,
|
||||
'os_family' => $this->OperatingSystemFamily,
|
||||
'os_version' => $this->OperatingSystemVersion,
|
||||
'device_family' => $this->DeviceFamily,
|
||||
'device_brand' => $this->DeviceBrand,
|
||||
'device_model' => $this->DeviceModel,
|
||||
'browser_family' => $this->BrowserFamily,
|
||||
'browser_version' => $this->BrowserVersion,
|
||||
'mobile_browser' => $this->MobileBrowser,
|
||||
'mobile_device' => $this->MobileDevice,
|
||||
'properties' => $this->Properties->toArray(),
|
||||
'last_seen_timestamp' => $this->LastSeenTimestamp,
|
||||
'created_timestamp' => $this->CreatedTimestamp
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs object from an array representation
|
||||
*
|
||||
* @param array $data
|
||||
* @return Device
|
||||
*/
|
||||
public static function fromArray(array $data): Device
|
||||
{
|
||||
$DeviceObject = new Device();
|
||||
|
||||
if(isset($data['fingerprint']))
|
||||
$DeviceObject->Fingerprint = $data['fingerprint'];
|
||||
|
||||
if(isset($data['user_agent']))
|
||||
$DeviceObject->UserAgent = $data['user_agent'];
|
||||
|
||||
if(isset($data['os_family']))
|
||||
$DeviceObject->OperatingSystemFamily = $data['os_version'];
|
||||
|
||||
if(isset($data['os_version']))
|
||||
$DeviceObject->OperatingSystemVersion = $data['os_version'];
|
||||
|
||||
if(isset($data['device_family']))
|
||||
$DeviceObject->DeviceFamily = $data['device_family'];
|
||||
|
||||
if(isset($data['device_brand']))
|
||||
$DeviceObject->DeviceBrand = $data['device_brand'];
|
||||
|
||||
if(isset($data['device_model']))
|
||||
$DeviceObject->DeviceModel = $data['device_model'];
|
||||
|
||||
if(isset($data['browser_family']))
|
||||
$DeviceObject->BrowserFamily = $data['browser_family'];
|
||||
|
||||
if(isset($data['browser_version']))
|
||||
$DeviceObject->BrowserVersion = $data['browser_version'];
|
||||
|
||||
if(isset($data['mobile_browser']))
|
||||
$DeviceObject->MobileBrowser = $data['mobile_browser'];
|
||||
|
||||
if(isset($data['mobile_device']))
|
||||
$DeviceObject->MobileDevice = $data['mobile_device'];
|
||||
|
||||
if(isset($data['properties']))
|
||||
$DeviceObject->Properties = Properties::fromArray($data['properties']);
|
||||
|
||||
if(isset($data['last_seen_timestamp']))
|
||||
$DeviceObject->LastSeenTimestamp = (int)$data['last_seen_timestamp'];
|
||||
|
||||
if(isset($data['created_timestamp']))
|
||||
$DeviceObject->CreatedTimestamp = (int)$data['created_timestamp'];
|
||||
|
||||
return $DeviceObject;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace khm\Objects\Device;
|
||||
|
||||
class Properties
|
||||
{
|
||||
/**
|
||||
* Returns an array representation of the object
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs object from an array representation
|
||||
*
|
||||
* @param array $data
|
||||
* @return Properties
|
||||
*/
|
||||
public static function fromArray(array $data): Properties
|
||||
{
|
||||
$PropertiesObject = new Properties();
|
||||
|
||||
return $PropertiesObject;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace khm\Objects;
|
||||
|
||||
use khm\Abstracts\HostFlags;
|
||||
|
||||
class QueryResults
|
||||
{
|
||||
/**
|
||||
* The queried IP address
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $IPAddress;
|
||||
|
||||
/**
|
||||
* The version of the IP address
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $IPVersion;
|
||||
|
||||
/**
|
||||
* Information about the IP addresses onion relay if available, otherwise null.
|
||||
*
|
||||
* @var OnionRelay|null
|
||||
*/
|
||||
public $Onion;
|
||||
|
||||
/**
|
||||
* Information about the IP addresses geolocation if available, otherwise null.
|
||||
*
|
||||
* @var GeoLookup|null
|
||||
*/
|
||||
public $Geo;
|
||||
|
||||
/**
|
||||
* Information about the abuse status of the IP address
|
||||
*
|
||||
* @var AbuseCheck|null
|
||||
*/
|
||||
public $Abuse;
|
||||
|
||||
/**
|
||||
* Flags associated with this IP address query
|
||||
*
|
||||
* @var string[]|HostFlags[]
|
||||
*/
|
||||
public $Flags;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
namespace khm\Objects;
|
||||
|
||||
|
||||
use khm\Abstracts\AbstractVersionedSoftware;
|
||||
|
||||
class UserAgent extends AbstractVersionedSoftware
|
||||
{
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
public $family;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
public $major;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
public $minor;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
public $patch;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function toVersion(): string
|
||||
{
|
||||
return $this->formatVersion($this->major, $this->minor, $this->patch);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace khm\Objects;
|
||||
|
||||
use khm\Abstracts\AbstractClient;
|
||||
|
||||
class UserAgentClient extends AbstractClient
|
||||
{
|
||||
/**
|
||||
* @var UserAgent
|
||||
*/
|
||||
public $ua;
|
||||
|
||||
/**
|
||||
* @var UserAgentOperatingSystem
|
||||
*/
|
||||
public $os;
|
||||
|
||||
/**
|
||||
* @var UserAgentDevice
|
||||
*/
|
||||
public $device;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $originalUserAgent;
|
||||
|
||||
/**
|
||||
* @param string $originalUserAgent
|
||||
*/
|
||||
public function __construct(string $originalUserAgent)
|
||||
{
|
||||
$this->originalUserAgent = $originalUserAgent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return $this->ua->toString().'/'.$this->os->toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace khm\Objects;
|
||||
|
||||
use khm\Abstracts\AbstractSoftware;
|
||||
|
||||
class UserAgentDevice extends AbstractSoftware
|
||||
{
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
public $brand;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
public $model;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace khm\Objects;
|
||||
|
||||
use khm\Abstracts\AbstractVersionedSoftware;
|
||||
|
||||
class UserAgentOperatingSystem extends AbstractVersionedSoftware
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
public $major;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
public $minor;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
public $patch;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
public $patchMinor;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function toVersion(): string
|
||||
{
|
||||
return $this->formatVersion($this->major, $this->minor, $this->patch, $this->patchMinor);
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i
|
|
@ -0,0 +1 @@
|
|||
/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i
|
File diff suppressed because it is too large
Load Diff
|
@ -13,6 +13,7 @@
|
|||
use khm\Exceptions\BadGeoSourceException;
|
||||
use khm\Exceptions\GeoRecordNotFoundException;
|
||||
use khm\Managers\AbuseManager;
|
||||
use khm\Managers\DevicesManager;
|
||||
use khm\Managers\GeoManager;
|
||||
use khm\Managers\OnionManager;
|
||||
use khm\Objects\AbuseCheck;
|
||||
|
@ -66,6 +67,11 @@
|
|||
*/
|
||||
private $OnionManager;
|
||||
|
||||
/**
|
||||
* @var DevicesManager
|
||||
*/
|
||||
private $DevicesManager;
|
||||
|
||||
/**
|
||||
* @throws ConfigurationNotDefinedException
|
||||
*/
|
||||
|
@ -101,6 +107,7 @@
|
|||
$this->AbuseManager = new AbuseManager($this);
|
||||
$this->GeoManager = new GeoManager($this);
|
||||
$this->OnionManager = new OnionManager($this);
|
||||
$this->DevicesManager = new DevicesManager($this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -338,4 +345,12 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DevicesManager
|
||||
*/
|
||||
public function getDevicesManager(): DevicesManager
|
||||
{
|
||||
return $this->DevicesManager;
|
||||
}
|
||||
}
|
|
@ -41,6 +41,18 @@
|
|||
}
|
||||
},
|
||||
"components": [
|
||||
{
|
||||
"required": true,
|
||||
"file": "Abstracts/AbstractSoftware.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Abstracts/SearchMethods/DeviceSearchMethod.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Abstracts/AbstractParser.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Abstracts/GeoLookupSource.php"
|
||||
|
@ -49,14 +61,54 @@
|
|||
"required": true,
|
||||
"file": "Abstracts/OnionVersionStatus.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Abstracts/AbstractClient.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Abstracts/AbstractVersionedSoftware.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Abstracts/HostFlags.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Classes/UserAgentParser.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Classes/DeviceDetection.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Classes/Curl.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Classes/RegexLoader.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Classes/UserAgentParser/DeviceParser.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Classes/UserAgentParser/OperatingSystemParser.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Classes/UserAgentParser/Parser.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "khm.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Exceptions/NoUserAgentProvidedException.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Exceptions/AbuseRecordNotFoundException.php"
|
||||
|
@ -73,6 +125,10 @@
|
|||
"required": true,
|
||||
"file": "Exceptions/KhmResolutionException.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Exceptions/DeviceRecordNotFoundException.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Exceptions/OnionRecordNotFoundException.php"
|
||||
|
@ -81,6 +137,10 @@
|
|||
"required": true,
|
||||
"file": "Exceptions/BadGeoSourceException.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Exceptions/InvalidSearchMethodException.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "ThirdParty/TorProject.php"
|
||||
|
@ -97,10 +157,38 @@
|
|||
"required": true,
|
||||
"file": "ThirdParty/IpAPIco.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Objects/UserAgentDevice.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Objects/UserAgent.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Objects/UserAgentClient.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Objects/QueryResults.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Objects/Device.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Objects/AbuseCheck.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Objects/Device/Properties.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Objects/UserAgentOperatingSystem.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Objects/GeoLookup.php"
|
||||
|
@ -120,10 +208,17 @@
|
|||
{
|
||||
"required": true,
|
||||
"file": "Managers/OnionManager.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Managers/DevicesManager.php"
|
||||
}
|
||||
],
|
||||
"files": [
|
||||
"package.json",
|
||||
"data/asn.json"
|
||||
"data/asn.json",
|
||||
"data/mobile2.regex",
|
||||
"data/regexes.json",
|
||||
"data/mobile1.regex"
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue