Fixed error 500 on logs and sessions pages because of dead library.

This commit is contained in:
flash 2023-07-21 11:33:27 +00:00
parent f32624c61d
commit ebac064c59
12 changed files with 99 additions and 186 deletions

6
.gitmodules vendored
View file

@ -1,3 +1,9 @@
[submodule "lib/index"]
path = lib/index
url = https://git.flash.moe/flash/index.git
[submodule "lib/device-detector"]
path = lib/device-detector
url = https://github.com/matomo-org/device-detector.git
[submodule "lib/spyc"]
path = lib/spyc
url = https://github.com/mustangostang/spyc.git

View file

@ -3,7 +3,6 @@
"twig/twig": "^3.0",
"erusev/parsedown": "~1.6",
"chillerlan/php-qrcode": "^4.3",
"whichbrowser/parser": "^2.0",
"symfony/mailer": "^6.0"
},
"autoload": {

115
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "26152622b2776a8d945647d5c1cfc48c",
"content-hash": "d757fc71803876a28a7434df1fa5edf1",
"packages": [
{
"name": "chillerlan/php-qrcode",
@ -342,55 +342,6 @@
},
"time": "2019-12-30T22:54:17+00:00"
},
{
"name": "psr/cache",
"version": "3.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/cache.git",
"reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf",
"reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf",
"shasum": ""
},
"require": {
"php": ">=8.0.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Cache\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common interface for caching libraries",
"keywords": [
"cache",
"psr",
"psr-6"
],
"support": {
"source": "https://github.com/php-fig/cache/tree/3.0.0"
},
"time": "2021-02-03T23:26:27+00:00"
},
{
"name": "psr/container",
"version": "2.0.2",
@ -1427,70 +1378,6 @@
}
],
"time": "2023-06-08T12:52:13+00:00"
},
{
"name": "whichbrowser/parser",
"version": "v2.1.7",
"source": {
"type": "git",
"url": "https://github.com/WhichBrowser/Parser-PHP.git",
"reference": "1044880bc792dbce5948fbff22ae731c43c280d9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/WhichBrowser/Parser-PHP/zipball/1044880bc792dbce5948fbff22ae731c43c280d9",
"reference": "1044880bc792dbce5948fbff22ae731c43c280d9",
"shasum": ""
},
"require": {
"php": ">=5.4.0",
"psr/cache": "^1.0 || ^2.0 || ^3.0"
},
"require-dev": {
"cache/array-adapter": "^1.1",
"icomefromthenet/reverse-regex": "0.0.6.3",
"php-coveralls/php-coveralls": "^2.0",
"phpunit/php-code-coverage": "^5.0 || ^7.0",
"phpunit/phpunit": "^6.0 || ^8.0",
"squizlabs/php_codesniffer": "^3.5",
"symfony/yaml": "~3.4 || ~4.0"
},
"suggest": {
"cache/array-adapter": "Allows testing of the caching functionality"
},
"type": "library",
"autoload": {
"psr-4": {
"WhichBrowser\\": [
"src/",
"tests/src/"
]
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Niels Leenheer",
"email": "niels@leenheer.nl",
"role": "Developer"
}
],
"description": "Useragent sniffing library for PHP",
"homepage": "http://whichbrowser.net",
"keywords": [
"browser",
"sniffing",
"ua",
"useragent"
],
"support": {
"issues": "https://github.com/WhichBrowser/Parser-PHP/issues",
"source": "https://github.com/WhichBrowser/Parser-PHP/tree/v2.1.7"
},
"time": "2022-04-19T20:14:54+00:00"
}
],
"packages-dev": [],

1
lib/device-detector Submodule

@ -0,0 +1 @@
Subproject commit 3e0fac7e77f3faadc3858fea9f5fa7efeb9cf239

1
lib/spyc Submodule

@ -0,0 +1 @@
Subproject commit 4627c838b16550b666d15aeae1e5289dd5b77da0

View file

@ -29,7 +29,12 @@ Environment::setDebug(MSZ_DEBUG);
mb_internal_encoding('utf-8');
date_default_timezone_set('utc');
// Third party libraries
require_once MSZ_ROOT . '/vendor/autoload.php';
require_once MSZ_LIBRARIES . '/spyc/Spyc.php'; // dependency for device-detector
require_once MSZ_LIBRARIES . '/device-detector/autoload.php';
// Procedural components
require_once MSZ_ROOT . '/utility.php';
require_once MSZ_SOURCE . '/perms.php';
require_once MSZ_SOURCE . '/manage.php';

View file

@ -111,8 +111,6 @@ if(CSRF::validateRequest() && $canEdit) {
}
if(!empty($_POST['user']) && is_array($_POST['user'])) {
//$setUsername = (string)($_POST['user']['username'] ?? '');
//$setEMailAddress = (string)($_POST['user']['email'] ?? '');
$setCountry = (string)($_POST['user']['country'] ?? '');
$setTitle = (string)($_POST['user']['title'] ?? '');
@ -122,21 +120,10 @@ if(CSRF::validateRequest() && $canEdit) {
$userInfo->setDisplayRole(UserRole::byId($displayRole));
} catch(UserRoleNotFoundException $ex) {}
//$usernameValidation = User::validateUsername($setUsername);
//$emailValidation = User::validateEMailAddress($setEMailAddress);
$countryValidation = strlen($setCountry) === 2
&& ctype_alpha($setCountry)
&& ctype_upper($setCountry);
//if(!empty($usernameValidation))
// $notices[] = User::usernameValidationErrorString($usernameValidation);
// if(!empty($emailValidation)) {
// $notices[] = $emailValidation === 'in-use'
// ? 'This e-mail address has already been used!'
// : 'This e-mail address is invalid!';
// }
if(!$countryValidation)
$notices[] = 'Country code was invalid.';
@ -144,10 +131,7 @@ if(CSRF::validateRequest() && $canEdit) {
$notices[] = 'User title was invalid.';
if(empty($notices))
$userInfo
// ->setUsername((string)($_POST['user']['username'] ?? ''))
// ->setEMailAddress((string)($_POST['user']['email'] ?? ''))
->setCountry((string)($_POST['user']['country'] ?? ''))
$userInfo->setCountry((string)($_POST['user']['country'] ?? ''))
->setTitle((string)($_POST['user']['title'] ?? ''))
->setDisplayRole(UserRole::byId((int)($_POST['user']['display_role'] ?? 0)));
}

76
src/ClientInfo.php Normal file
View file

@ -0,0 +1,76 @@
<?php
namespace Misuzu;
use InvalidArgumentException;
use Stringable;
use DeviceDetector\ClientHints;
use DeviceDetector\DeviceDetector;
class ClientInfo implements Stringable {
private DeviceDetector $dd;
public function __construct(DeviceDetector $dd) {
$this->dd = $dd;
}
public function __toString(): string {
if($this->dd->isBot()) {
$botInfo = $this->dd->getBot();
return $botInfo['name'] ?? 'an unknown bot';
}
$clientInfo = $this->dd->getClient();
if(empty($clientInfo['name']))
return 'an unknown browser';
$string = $clientInfo['name'];
if(!empty($clientInfo['version']))
$string .= ' ' . $clientInfo['version'];
$osInfo = $this->dd->getOs();
$hasOsInfo = !empty($osInfo['name']);
$brandName = $this->dd->getBrandName();
$modelName = $this->dd->getModel();
$hasModelName = !empty($modelName);
if($hasOsInfo || $hasModelName)
$string .= ' on ';
if($hasModelName) {
$deviceName = trim($brandName . ' ' . $modelName);
// most naive check in the world but it works well enough for this lol
$firstCharIsVowel = in_array(strtolower($deviceName[0]), ['a', 'i', 'u', 'e', 'o']);
$string .= ($firstCharIsVowel ? 'an' : 'a') . ' ' . $deviceName;
}
if($hasOsInfo) {
if($hasModelName)
$string .= ' running ';
$string .= $osInfo['name'];
if(!empty($osInfo['version']))
$string .= ' ' . $osInfo['version'];
if(!empty($osInfo['platform']))
$string .= ' (' . $osInfo['platform'] . ')';
}
return $string;
}
public static function parse(array|string $serverVarsOrUserAgent): self {
if(is_string($serverVarsOrUserAgent)) {
$userAgent = $serverVarsOrUserAgent;
$clientHints = null;
} else {
$userAgent = array_key_exists('HTTP_USER_AGENT', $serverVarsOrUserAgent)
? $serverVarsOrUserAgent['HTTP_USER_AGENT'] : '';
$clientHints = ClientHints::factory($serverVarsOrUserAgent);
}
$dd = new DeviceDetector($userAgent, $clientHints);
$dd->parse();
return new static($dd);
}
}

View file

@ -92,18 +92,10 @@ class User implements HasRankInterface {
public function getUsername(): string {
return $this->username;
}
public function setUsername(string $username): self {
$this->username = $username;
return $this;
}
public function getEmailAddress(): string {
return $this->email;
}
public function setEmailAddress(string $address): self {
$this->email = mb_strtolower($address);
return $this;
}
public function getRegisterRemoteAddress(): string {
return $this->register_ip ?? '::1';
@ -115,10 +107,6 @@ class User implements HasRankInterface {
public function isSuper(): bool {
return boolval($this->user_super);
}
public function setSuper(bool $super): self {
$this->user_super = $super ? 1 : 0;
return $this;
}
public function hasCountry(): bool {
return $this->user_country !== 'XX';
@ -400,40 +388,12 @@ class User implements HasRankInterface {
* DELETING *
************/
private const NUKE_TIMEOUT = 600;
public function getDeletedTime(): int {
return $this->user_deleted === null ? -1 : $this->user_deleted;
}
public function isDeleted(): bool {
return $this->getDeletedTime() >= 0;
}
public function delete(): void {
if($this->isDeleted())
return;
$this->user_deleted = time();
DB::prepare('UPDATE `' . DB::PREFIX . self::TABLE . '` SET `user_deleted` = NOW() WHERE `user_id` = :user')
->bind('user', $this->user_id)
->execute();
}
public function restore(): void {
if(!$this->isDeleted())
return;
$this->user_deleted = null;
DB::prepare('UPDATE `' . DB::PREFIX . self::TABLE . '` SET `user_deleted` = NULL WHERE `user_id` = :user')
->bind('user', $this->user_id)
->execute();
}
public function canBeNuked(): bool {
return $this->isDeleted() && time() > $this->getDeletedTime() + self::NUKE_TIMEOUT;
}
public function nuke(): void {
if(!$this->canBeNuked())
return;
DB::prepare('DELETE FROM `' . DB::PREFIX . self::TABLE . '` WHERE `user_id` = :user')
->bind('user', $this->user_id)
->execute();
}
/**********
* ASSETS *

View file

@ -1,9 +1,9 @@
<?php
namespace Misuzu\Users;
use Misuzu\ClientInfo;
use Misuzu\DB;
use Misuzu\Pagination;
use WhichBrowser\Parser as UserAgentParser;
class UserLoginAttempt {
// Database fields
@ -16,7 +16,6 @@ class UserLoginAttempt {
private $user = null;
private $userLookedUp = false;
private $uaInfo = null;
public const TABLE = 'login_attempts';
private const QUERY_SELECT = 'SELECT %1$s FROM `' . DB::PREFIX . self::TABLE . '` AS '. self::TABLE;
@ -59,10 +58,8 @@ class UserLoginAttempt {
public function getUserAgent(): string {
return $this->attempt_user_agent;
}
public function getUserAgentInfo(): UserAgentParser {
if($this->uaInfo === null)
$this->uaInfo = new UserAgentParser($this->getUserAgent());
return $this->uaInfo;
public function getClientString(): string {
return (string)ClientInfo::parse($this->attempt_user_agent);
}
public static function remaining(string $remoteAddr): int {

View file

@ -1,9 +1,9 @@
<?php
namespace Misuzu\Users;
use Misuzu\ClientInfo;
use Misuzu\DB;
use Misuzu\Pagination;
use WhichBrowser\Parser as UserAgentParser;
class UserSessionException extends UsersException {}
class UserSessionCreationFailedException extends UserSessionException {}
@ -27,7 +27,6 @@ class UserSession {
private $session_active = null;
private $user = null;
private $uaInfo = null;
private static $localSession = null;
@ -75,10 +74,8 @@ class UserSession {
public function getUserAgent(): string {
return $this->session_user_agent;
}
public function getUserAgentInfo(): UserAgentParser {
if($this->uaInfo === null)
$this->uaInfo = new UserAgentParser($this->getUserAgent());
return $this->uaInfo;
public function getClientString(): string {
return (string)ClientInfo::parse($this->session_user_agent);
}
public function getCountry(): string {

View file

@ -73,7 +73,7 @@
<div class="flag flag--{{ session.country|lower }} settings__session__flag" title="{{ session.countryName }}">{{ session.country }}</div>
<div class="settings__session__description">
{{ session.userAgentInfo.toString }}
{{ session.clientString }}
</div>
<form class="settings__session__actions" method="post" action="{{ url('settings-sessions') }}">
@ -160,7 +160,7 @@
<div class="flag flag--{{ attempt.country|lower }} settings__login-attempt__flag" title="{{ attempt.countryName }}">{{ attempt.country }}</div>
<div class="settings__login-attempt__description">
{{ attempt.userAgentInfo.toString }}
{{ attempt.clientString }}
</div>
</div>