mirror of
https://github.com/elyby/accounts.git
synced 2025-05-31 14:11:46 +05:30
Drop usage of goaop, replace implementation with events
This commit is contained in:
@@ -1,17 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace api\aop;
|
|
||||||
|
|
||||||
use Doctrine\Common\Annotations\AnnotationReader;
|
|
||||||
use Go\Core\AspectContainer;
|
|
||||||
use Go\Core\AspectKernel as BaseAspectKernel;
|
|
||||||
|
|
||||||
class AspectKernel extends BaseAspectKernel {
|
|
||||||
|
|
||||||
protected function configureAop(AspectContainer $container): void {
|
|
||||||
AnnotationReader::addGlobalIgnoredName('url');
|
|
||||||
|
|
||||||
$container->registerAspect(new aspects\MockDataAspect());
|
|
||||||
$container->registerAspect(new aspects\CollectMetricsAspect());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,21 +0,0 @@
|
|||||||
<?php
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace api\aop\annotations;
|
|
||||||
|
|
||||||
use Doctrine\Common\Annotations\Annotation;
|
|
||||||
use Doctrine\Common\Annotations\Annotation\Required;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Annotation
|
|
||||||
* @Target("METHOD")
|
|
||||||
*/
|
|
||||||
class CollectModelMetrics {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Required()
|
|
||||||
* @var string sets the prefix for collected metrics. Should be specified without trailing dots
|
|
||||||
*/
|
|
||||||
public $prefix = '';
|
|
||||||
|
|
||||||
}
|
|
@@ -1,41 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace api\aop\aspects;
|
|
||||||
|
|
||||||
use api\aop\annotations\CollectModelMetrics;
|
|
||||||
use Go\Aop\Aspect;
|
|
||||||
use Go\Aop\Intercept\MethodInvocation;
|
|
||||||
use Go\Lang\Annotation\Around;
|
|
||||||
use Yii;
|
|
||||||
|
|
||||||
class CollectMetricsAspect implements Aspect {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param MethodInvocation $invocation Invocation
|
|
||||||
* @Around("@execution(api\aop\annotations\CollectModelMetrics)")
|
|
||||||
*/
|
|
||||||
public function sendMetrics(MethodInvocation $invocation) {
|
|
||||||
/** @var CollectModelMetrics $annotation */
|
|
||||||
$annotation = $invocation->getMethod()->getAnnotation(CollectModelMetrics::class);
|
|
||||||
$prefix = trim($annotation->prefix, '.');
|
|
||||||
|
|
||||||
Yii::$app->statsd->inc($prefix . '.attempt');
|
|
||||||
$result = $invocation->proceed();
|
|
||||||
if ($result !== false) {
|
|
||||||
Yii::$app->statsd->inc($prefix . '.success');
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @var \yii\base\Model $model */
|
|
||||||
$model = $invocation->getThis();
|
|
||||||
$errors = array_values($model->getFirstErrors());
|
|
||||||
if (!isset($errors[0])) {
|
|
||||||
Yii::error('Unsuccess result with empty errors list');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Yii::$app->statsd->inc($prefix . '.' . $errors[0]);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,177 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace api\aop\aspects;
|
|
||||||
|
|
||||||
use Go\Aop\Aspect;
|
|
||||||
use Go\Aop\Intercept\MethodInvocation;
|
|
||||||
use Go\Lang\Annotation\Around;
|
|
||||||
use Yii;
|
|
||||||
use yii\web\Request;
|
|
||||||
|
|
||||||
class MockDataAspect implements Aspect {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param MethodInvocation $invocation Invocation
|
|
||||||
* @Around("execution(public api\controllers\SignupController->actionIndex(*))")
|
|
||||||
*/
|
|
||||||
public function beforeSignup(MethodInvocation $invocation) {
|
|
||||||
$email = $this->getRequest()->post('email');
|
|
||||||
if ($email === 'let-me-register@ely.by') {
|
|
||||||
return ['success' => true];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $invocation->proceed();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param MethodInvocation $invocation
|
|
||||||
* @Around("execution(public api\controllers\SignupController->actionRepeatMessage(*))")
|
|
||||||
*/
|
|
||||||
public function beforeRepeatMessage(MethodInvocation $invocation) {
|
|
||||||
$email = $this->getRequest()->post('email');
|
|
||||||
if ($email === 'let-me-register@ely.by' || $email === 'let-me-repeat@ely.by') {
|
|
||||||
return ['success' => true];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $invocation->proceed();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param MethodInvocation $invocation
|
|
||||||
* @Around("execution(public api\controllers\SignupController->actionConfirm(*))")
|
|
||||||
*/
|
|
||||||
public function beforeSignupConfirm(MethodInvocation $invocation) {
|
|
||||||
$email = $this->getRequest()->post('key');
|
|
||||||
if ($email === 'LETMEIN') {
|
|
||||||
return [
|
|
||||||
'success' => true,
|
|
||||||
'access_token' => 'dummy_token',
|
|
||||||
'expires_in' => time() + 60,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $invocation->proceed();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param MethodInvocation $invocation
|
|
||||||
* @Around("execution(public api\controllers\AuthenticationController->actionForgotPassword(*))")
|
|
||||||
*/
|
|
||||||
public function beforeForgotPassword(MethodInvocation $invocation) {
|
|
||||||
$login = $this->getRequest()->post('login');
|
|
||||||
if ($login === 'let-me-recover@ely.by') {
|
|
||||||
return [
|
|
||||||
'success' => true,
|
|
||||||
'data' => [
|
|
||||||
'canRepeatIn' => time() + 60,
|
|
||||||
'repeatFrequency' => 60,
|
|
||||||
],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $invocation->proceed();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param MethodInvocation $invocation
|
|
||||||
* @Around("execution(public api\controllers\AuthenticationController->actionRecoverPassword(*))")
|
|
||||||
*/
|
|
||||||
public function beforeRecoverPassword(MethodInvocation $invocation) {
|
|
||||||
$key = $this->getRequest()->post('key');
|
|
||||||
if ($key === 'LETMEIN') {
|
|
||||||
return [
|
|
||||||
'success' => true,
|
|
||||||
'access_token' => 'dummy_token',
|
|
||||||
'expires_in' => time() + 60,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $invocation->proceed();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param MethodInvocation $invocation
|
|
||||||
* @Around("execution(public api\modules\accounts\controllers\DefaultController->actionGet(*))")
|
|
||||||
*/
|
|
||||||
public function beforeAccountGet(MethodInvocation $invocation) {
|
|
||||||
$httpAuth = $this->getRequest()->getHeaders()->get('authorization');
|
|
||||||
if ($httpAuth === 'Bearer dummy_token') {
|
|
||||||
return [
|
|
||||||
'id' => 1,
|
|
||||||
'uuid' => 'f63cd5e1-680f-4c2d-baa2-cc7bb174b71a',
|
|
||||||
'username' => 'dummy',
|
|
||||||
'isOtpEnabled' => false,
|
|
||||||
'registeredAt' => time(),
|
|
||||||
'lang' => 'en',
|
|
||||||
'elyProfileLink' => 'http://ely.by/u1',
|
|
||||||
'email' => 'let-me-register@ely.by',
|
|
||||||
'isActive' => true,
|
|
||||||
'passwordChangedAt' => time(),
|
|
||||||
'hasMojangUsernameCollision' => false,
|
|
||||||
'shouldAcceptRules' => false,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $invocation->proceed();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param MethodInvocation $invocation
|
|
||||||
* @Around("execution(public api\modules\accounts\actions\EmailVerificationAction->run(*))")
|
|
||||||
*/
|
|
||||||
public function beforeAccountEmailVerification(MethodInvocation $invocation) {
|
|
||||||
$httpAuth = $this->getRequest()->getHeaders()->get('authorization');
|
|
||||||
if ($httpAuth === 'Bearer dummy_token') {
|
|
||||||
$password = $this->getRequest()->post('password');
|
|
||||||
if (empty($password)) {
|
|
||||||
return [
|
|
||||||
'success' => false,
|
|
||||||
'errors' => [
|
|
||||||
'password' => 'error.password_required',
|
|
||||||
],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return [
|
|
||||||
'success' => true,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $invocation->proceed();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param MethodInvocation $invocation
|
|
||||||
* @Around("execution(public api\modules\accounts\actions\NewEmailVerificationAction->run(*))")
|
|
||||||
*/
|
|
||||||
public function beforeAccountNewEmailVerification(MethodInvocation $invocation) {
|
|
||||||
$key = $this->getRequest()->post('key');
|
|
||||||
if ($key === 'LETMEIN') {
|
|
||||||
return [
|
|
||||||
'success' => true,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $invocation->proceed();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param MethodInvocation $invocation
|
|
||||||
* @Around("execution(public api\modules\accounts\actions\ChangeEmailAction->run(*))")
|
|
||||||
*/
|
|
||||||
public function beforeAccountChangeEmail(MethodInvocation $invocation) {
|
|
||||||
$key = $this->getRequest()->post('key');
|
|
||||||
if ($key === 'LETMEIN') {
|
|
||||||
return [
|
|
||||||
'success' => true,
|
|
||||||
'email' => 'brand-new-email@ely.by',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $invocation->proceed();
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getRequest(): Request {
|
|
||||||
return Yii::$app->getRequest();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -2,7 +2,14 @@
|
|||||||
return [
|
return [
|
||||||
'id' => 'accounts-site-api',
|
'id' => 'accounts-site-api',
|
||||||
'basePath' => dirname(__DIR__),
|
'basePath' => dirname(__DIR__),
|
||||||
'bootstrap' => ['log', 'authserver', 'internal', 'mojang'],
|
'bootstrap' => [
|
||||||
|
'log',
|
||||||
|
'authserver',
|
||||||
|
'internal',
|
||||||
|
'mojang',
|
||||||
|
api\eventListeners\MockDataResponse::class,
|
||||||
|
api\eventListeners\LogMetricsToStatsd::class,
|
||||||
|
],
|
||||||
'controllerNamespace' => 'api\controllers',
|
'controllerNamespace' => 'api\controllers',
|
||||||
'params' => [
|
'params' => [
|
||||||
'authserverHost' => getenv('AUTHSERVER_HOST') ?: 'authserver.ely.by',
|
'authserverHost' => getenv('AUTHSERVER_HOST') ?: 'authserver.ely.by',
|
||||||
|
85
api/eventListeners/LogMetricsToStatsd.php
Normal file
85
api/eventListeners/LogMetricsToStatsd.php
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace api\eventListeners;
|
||||||
|
|
||||||
|
use api\controllers\AuthenticationController;
|
||||||
|
use api\controllers\SignupController;
|
||||||
|
use api\modules\accounts\actions;
|
||||||
|
use Closure;
|
||||||
|
use Yii;
|
||||||
|
use yii\base\ActionEvent;
|
||||||
|
use yii\base\BootstrapInterface;
|
||||||
|
use yii\base\Controller;
|
||||||
|
use yii\base\Event;
|
||||||
|
|
||||||
|
final class LogMetricsToStatsd implements BootstrapInterface {
|
||||||
|
|
||||||
|
public function bootstrap($app): void {
|
||||||
|
Event::on(Controller::class, Controller::EVENT_BEFORE_ACTION, Closure::fromCallable([$this, 'beforeAction']));
|
||||||
|
Event::on(Controller::class, Controller::EVENT_AFTER_ACTION, Closure::fromCallable([$this, 'afterAction']));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function beforeAction(ActionEvent $event): void {
|
||||||
|
$prefix = $this->getPrefix($event);
|
||||||
|
if ($prefix === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Yii::$app->statsd->inc($prefix . '.attempt');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function afterAction(ActionEvent $event): void {
|
||||||
|
$prefix = $this->getPrefix($event);
|
||||||
|
if ($prefix === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $event->result;
|
||||||
|
if (isset($result['success'])) {
|
||||||
|
if ($result['success']) {
|
||||||
|
Yii::$app->statsd->inc($prefix . '.success');
|
||||||
|
} else {
|
||||||
|
$errors = $result['errors'];
|
||||||
|
Yii::$app->statsd->inc($prefix . '.' . $errors[array_key_first($errors)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getPrefix(ActionEvent $event): ?string {
|
||||||
|
$action = $event->action;
|
||||||
|
switch (get_class($action)) {
|
||||||
|
case actions\AcceptRulesAction::class: return 'accounts.acceptRules';
|
||||||
|
case actions\ChangeEmailAction::class: return 'accounts.changeEmail';
|
||||||
|
case actions\ChangeLanguageAction::class: return 'accounts.switchLanguage';
|
||||||
|
case actions\ChangePasswordAction::class: return 'accounts.changePassword';
|
||||||
|
case actions\ChangeUsernameAction::class: return 'accounts.changeUsername';
|
||||||
|
case actions\EnableTwoFactorAuthAction::class: return 'accounts.enableTwoFactorAuth';
|
||||||
|
case actions\DisableTwoFactorAuthAction::class: return 'accounts.disableTwoFactorAuth';
|
||||||
|
case actions\EmailVerificationAction::class: return 'accounts.sendEmailVerification';
|
||||||
|
case actions\NewEmailVerificationAction::class: return 'accounts.sendNewEmailVerification';
|
||||||
|
}
|
||||||
|
|
||||||
|
$controller = $action->controller;
|
||||||
|
if ($controller instanceof SignupController) {
|
||||||
|
switch ($action->id) {
|
||||||
|
case 'index': return 'signup.register';
|
||||||
|
case 'repeatMessage': return 'signup.repeatEmail';
|
||||||
|
case 'confirm': return 'signup.confirmEmail';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($controller instanceof AuthenticationController) {
|
||||||
|
switch ($action->id) {
|
||||||
|
case 'login': return 'authentication.login';
|
||||||
|
case 'logout': return 'authentication.logout';
|
||||||
|
case 'forgotPassword': return 'authentication.forgotPassword';
|
||||||
|
case 'recoverPassword': return 'authentication.recoverPassword';
|
||||||
|
case 'refreshToken': return 'authentication.renew';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
153
api/eventListeners/MockDataResponse.php
Normal file
153
api/eventListeners/MockDataResponse.php
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace api\eventListeners;
|
||||||
|
|
||||||
|
use api\controllers\AuthenticationController;
|
||||||
|
use api\controllers\SignupController;
|
||||||
|
use api\modules\accounts\actions\ChangeEmailAction;
|
||||||
|
use api\modules\accounts\actions\EmailVerificationAction;
|
||||||
|
use api\modules\accounts\actions\NewEmailVerificationAction;
|
||||||
|
use api\modules\accounts\controllers\DefaultController;
|
||||||
|
use Closure;
|
||||||
|
use yii\base\ActionEvent;
|
||||||
|
use yii\base\BootstrapInterface;
|
||||||
|
use yii\base\Controller;
|
||||||
|
use yii\base\Event;
|
||||||
|
use yii\web\Response;
|
||||||
|
|
||||||
|
final class MockDataResponse implements BootstrapInterface {
|
||||||
|
|
||||||
|
public function bootstrap($app): void {
|
||||||
|
Event::on(Controller::class, Controller::EVENT_BEFORE_ACTION, Closure::fromCallable([$this, 'beforeAction']));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function beforeAction(ActionEvent $event): void {
|
||||||
|
$result = $this->getResponse($event);
|
||||||
|
if ($result === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = $event->action->controller->response;
|
||||||
|
$response->format = Response::FORMAT_JSON;
|
||||||
|
$response->data = $result;
|
||||||
|
|
||||||
|
$event->handled = true;
|
||||||
|
$event->isValid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getResponse(ActionEvent $event): ?array {
|
||||||
|
$action = $event->action;
|
||||||
|
$controller = $action->controller;
|
||||||
|
$request = $controller->request;
|
||||||
|
if ($controller instanceof SignupController && $action->id === 'index') {
|
||||||
|
$email = $request->post('email');
|
||||||
|
if ($email === 'let-me-register@ely.by') {
|
||||||
|
return ['success' => true];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($controller instanceof SignupController && $action->id === 'repeatMessage') {
|
||||||
|
$email = $request->post('email');
|
||||||
|
if ($email === 'let-me-register@ely.by' || $email === 'let-me-repeat@ely.by') {
|
||||||
|
return ['success' => true];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($controller instanceof SignupController && $action->id === 'confirm') {
|
||||||
|
$key = $request->post('key');
|
||||||
|
if ($key === 'LETMEIN') {
|
||||||
|
return [
|
||||||
|
'success' => true,
|
||||||
|
'access_token' => 'dummy_token',
|
||||||
|
'expires_in' => time() + 60,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($controller instanceof AuthenticationController && $action->id === 'forgotPassword') {
|
||||||
|
$login = $request->post('login');
|
||||||
|
if ($login === 'let-me-recover@ely.by') {
|
||||||
|
return [
|
||||||
|
'success' => true,
|
||||||
|
'data' => [
|
||||||
|
'canRepeatIn' => time() + 60,
|
||||||
|
'repeatFrequency' => 60,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($controller instanceof AuthenticationController && $action->id === 'recoverPassword') {
|
||||||
|
$key = $request->post('key');
|
||||||
|
if ($key === 'LETMEIN') {
|
||||||
|
return [
|
||||||
|
'success' => true,
|
||||||
|
'access_token' => 'dummy_token',
|
||||||
|
'expires_in' => time() + 60,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($controller instanceof DefaultController && $action->id === 'get') {
|
||||||
|
$httpAuth = $request->getHeaders()->get('authorization');
|
||||||
|
if ($httpAuth === 'Bearer dummy_token') {
|
||||||
|
return [
|
||||||
|
'id' => 1,
|
||||||
|
'uuid' => 'f63cd5e1-680f-4c2d-baa2-cc7bb174b71a',
|
||||||
|
'username' => 'dummy',
|
||||||
|
'isOtpEnabled' => false,
|
||||||
|
'registeredAt' => time(),
|
||||||
|
'lang' => 'en',
|
||||||
|
'elyProfileLink' => 'http://ely.by/u1',
|
||||||
|
'email' => 'let-me-register@ely.by',
|
||||||
|
'isActive' => true,
|
||||||
|
'passwordChangedAt' => time(),
|
||||||
|
'hasMojangUsernameCollision' => false,
|
||||||
|
'shouldAcceptRules' => false,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($action instanceof EmailVerificationAction) {
|
||||||
|
$httpAuth = $request->getHeaders()->get('authorization');
|
||||||
|
if ($httpAuth === 'Bearer dummy_token') {
|
||||||
|
$password = $request->post('password');
|
||||||
|
if (empty($password)) {
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'errors' => [
|
||||||
|
'password' => 'error.password_required',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'success' => true,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($action instanceof NewEmailVerificationAction) {
|
||||||
|
$key = $request->post('key');
|
||||||
|
if ($key === 'LETMEIN') {
|
||||||
|
return [
|
||||||
|
'success' => true,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($action instanceof ChangeEmailAction) {
|
||||||
|
$key = $request->post('key');
|
||||||
|
if ($key === 'LETMEIN') {
|
||||||
|
return [
|
||||||
|
'success' => true,
|
||||||
|
'email' => 'brand-new-email@ely.by',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -1,6 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use api\aop\AspectKernel;
|
|
||||||
use common\config\ConfigLoader;
|
use common\config\ConfigLoader;
|
||||||
use yii\web\Application;
|
use yii\web\Application;
|
||||||
|
|
||||||
@@ -11,17 +10,6 @@ require __DIR__ . '/../vendor/autoload.php';
|
|||||||
defined('YII_DEBUG') || define('YII_DEBUG', in_array(getenv('YII_DEBUG'), ['true', '1'], false));
|
defined('YII_DEBUG') || define('YII_DEBUG', in_array(getenv('YII_DEBUG'), ['true', '1'], false));
|
||||||
defined('YII_ENV') || define('YII_ENV', getenv('YII_ENV'));
|
defined('YII_ENV') || define('YII_ENV', getenv('YII_ENV'));
|
||||||
|
|
||||||
// Initialize an application aspect container
|
|
||||||
AspectKernel::getInstance()->init([
|
|
||||||
'debug' => YII_DEBUG,
|
|
||||||
'appDir' => dirname(__DIR__),
|
|
||||||
'cacheDir' => __DIR__ . '/runtime/aspect',
|
|
||||||
'excludePaths' => [
|
|
||||||
__DIR__ . '/runtime/aspect',
|
|
||||||
__DIR__ . '/../vendor',
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
|
|
||||||
require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php';
|
require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php';
|
||||||
require __DIR__ . '/../common/config/bootstrap.php';
|
require __DIR__ . '/../common/config/bootstrap.php';
|
||||||
require __DIR__ . '/config/bootstrap.php';
|
require __DIR__ . '/config/bootstrap.php';
|
||||||
|
@@ -3,7 +3,6 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace api\models\authentication;
|
namespace api\models\authentication;
|
||||||
|
|
||||||
use api\aop\annotations\CollectModelMetrics;
|
|
||||||
use api\models\base\ApiForm;
|
use api\models\base\ApiForm;
|
||||||
use api\validators\EmailActivationKeyValidator;
|
use api\validators\EmailActivationKeyValidator;
|
||||||
use common\models\Account;
|
use common\models\Account;
|
||||||
@@ -22,9 +21,6 @@ class ConfirmEmailForm extends ApiForm {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @CollectModelMetrics(prefix="signup.confirmEmail")
|
|
||||||
*/
|
|
||||||
public function confirm(): ?AuthenticationResult {
|
public function confirm(): ?AuthenticationResult {
|
||||||
if (!$this->validate()) {
|
if (!$this->validate()) {
|
||||||
return null;
|
return null;
|
||||||
|
@@ -3,7 +3,6 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace api\models\authentication;
|
namespace api\models\authentication;
|
||||||
|
|
||||||
use api\aop\annotations\CollectModelMetrics;
|
|
||||||
use api\components\ReCaptcha\Validator as ReCaptchaValidator;
|
use api\components\ReCaptcha\Validator as ReCaptchaValidator;
|
||||||
use api\models\base\ApiForm;
|
use api\models\base\ApiForm;
|
||||||
use common\components\UserFriendlyRandomKey;
|
use common\components\UserFriendlyRandomKey;
|
||||||
@@ -61,10 +60,6 @@ class ForgotPasswordForm extends ApiForm {
|
|||||||
return Account::find()->andWhereLogin($this->login)->one();
|
return Account::find()->andWhereLogin($this->login)->one();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @CollectModelMetrics(prefix="authentication.forgotPassword")
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function forgotPassword(): bool {
|
public function forgotPassword(): bool {
|
||||||
if (!$this->validate()) {
|
if (!$this->validate()) {
|
||||||
return false;
|
return false;
|
||||||
|
@@ -3,7 +3,6 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace api\models\authentication;
|
namespace api\models\authentication;
|
||||||
|
|
||||||
use api\aop\annotations\CollectModelMetrics;
|
|
||||||
use api\models\base\ApiForm;
|
use api\models\base\ApiForm;
|
||||||
use api\validators\TotpValidator;
|
use api\validators\TotpValidator;
|
||||||
use common\helpers\Error as E;
|
use common\helpers\Error as E;
|
||||||
@@ -104,9 +103,6 @@ class LoginForm extends ApiForm {
|
|||||||
return Account::find()->andWhereLogin($this->login)->one();
|
return Account::find()->andWhereLogin($this->login)->one();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @CollectModelMetrics(prefix="authentication.login")
|
|
||||||
*/
|
|
||||||
public function login(): ?AuthenticationResult {
|
public function login(): ?AuthenticationResult {
|
||||||
if (!$this->validate()) {
|
if (!$this->validate()) {
|
||||||
return null;
|
return null;
|
||||||
|
@@ -3,16 +3,11 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace api\models\authentication;
|
namespace api\models\authentication;
|
||||||
|
|
||||||
use api\aop\annotations\CollectModelMetrics;
|
|
||||||
use api\models\base\ApiForm;
|
use api\models\base\ApiForm;
|
||||||
use Yii;
|
use Yii;
|
||||||
|
|
||||||
class LogoutForm extends ApiForm {
|
class LogoutForm extends ApiForm {
|
||||||
|
|
||||||
/**
|
|
||||||
* @CollectModelMetrics(prefix="authentication.logout")
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function logout(): bool {
|
public function logout(): bool {
|
||||||
$component = Yii::$app->user;
|
$component = Yii::$app->user;
|
||||||
$session = $component->getActiveSession();
|
$session = $component->getActiveSession();
|
||||||
|
@@ -3,7 +3,6 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace api\models\authentication;
|
namespace api\models\authentication;
|
||||||
|
|
||||||
use api\aop\annotations\CollectModelMetrics;
|
|
||||||
use api\models\base\ApiForm;
|
use api\models\base\ApiForm;
|
||||||
use api\validators\EmailActivationKeyValidator;
|
use api\validators\EmailActivationKeyValidator;
|
||||||
use common\helpers\Error as E;
|
use common\helpers\Error as E;
|
||||||
@@ -36,9 +35,6 @@ class RecoverPasswordForm extends ApiForm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @CollectModelMetrics(prefix="authentication.recoverPassword")
|
|
||||||
*/
|
|
||||||
public function recoverPassword(): ?AuthenticationResult {
|
public function recoverPassword(): ?AuthenticationResult {
|
||||||
if (!$this->validate()) {
|
if (!$this->validate()) {
|
||||||
return null;
|
return null;
|
||||||
|
@@ -3,7 +3,6 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace api\models\authentication;
|
namespace api\models\authentication;
|
||||||
|
|
||||||
use api\aop\annotations\CollectModelMetrics;
|
|
||||||
use api\models\base\ApiForm;
|
use api\models\base\ApiForm;
|
||||||
use common\helpers\Error as E;
|
use common\helpers\Error as E;
|
||||||
use common\models\AccountSession;
|
use common\models\AccountSession;
|
||||||
@@ -32,9 +31,6 @@ class RefreshTokenForm extends ApiForm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @CollectModelMetrics(prefix="authentication.renew")
|
|
||||||
*/
|
|
||||||
public function renew(): ?AuthenticationResult {
|
public function renew(): ?AuthenticationResult {
|
||||||
if (!$this->validate()) {
|
if (!$this->validate()) {
|
||||||
return null;
|
return null;
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace api\models\authentication;
|
namespace api\models\authentication;
|
||||||
|
|
||||||
use api\aop\annotations\CollectModelMetrics;
|
|
||||||
use api\components\ReCaptcha\Validator as ReCaptchaValidator;
|
use api\components\ReCaptcha\Validator as ReCaptchaValidator;
|
||||||
use api\models\base\ApiForm;
|
use api\models\base\ApiForm;
|
||||||
use common\components\UserFriendlyRandomKey;
|
use common\components\UserFriendlyRandomKey;
|
||||||
@@ -63,11 +62,6 @@ class RegistrationForm extends ApiForm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @CollectModelMetrics(prefix="signup.register")
|
|
||||||
* @return Account|null the saved model or null if saving fails
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public function signup() {
|
public function signup() {
|
||||||
if (!$this->validate() && !$this->canContinue($this->getFirstErrors())) {
|
if (!$this->validate() && !$this->canContinue($this->getFirstErrors())) {
|
||||||
return null;
|
return null;
|
||||||
|
@@ -3,7 +3,6 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace api\models\authentication;
|
namespace api\models\authentication;
|
||||||
|
|
||||||
use api\aop\annotations\CollectModelMetrics;
|
|
||||||
use api\components\ReCaptcha\Validator as ReCaptchaValidator;
|
use api\components\ReCaptcha\Validator as ReCaptchaValidator;
|
||||||
use api\models\base\ApiForm;
|
use api\models\base\ApiForm;
|
||||||
use common\components\UserFriendlyRandomKey;
|
use common\components\UserFriendlyRandomKey;
|
||||||
@@ -56,10 +55,6 @@ class RepeatAccountActivationForm extends ApiForm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @CollectModelMetrics(prefix="signup.repeatEmail")
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function sendRepeatMessage(): bool {
|
public function sendRepeatMessage(): bool {
|
||||||
if (!$this->validate()) {
|
if (!$this->validate()) {
|
||||||
return false;
|
return false;
|
||||||
|
@@ -1,15 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace api\modules\accounts\models;
|
namespace api\modules\accounts\models;
|
||||||
|
|
||||||
use api\aop\annotations\CollectModelMetrics;
|
|
||||||
use yii\base\ErrorException;
|
use yii\base\ErrorException;
|
||||||
use const common\LATEST_RULES_VERSION;
|
use const common\LATEST_RULES_VERSION;
|
||||||
|
|
||||||
class AcceptRulesForm extends AccountActionForm {
|
class AcceptRulesForm extends AccountActionForm {
|
||||||
|
|
||||||
/**
|
|
||||||
* @CollectModelMetrics(prefix="accounts.acceptRules")
|
|
||||||
*/
|
|
||||||
public function performAction(): bool {
|
public function performAction(): bool {
|
||||||
$account = $this->getAccount();
|
$account = $this->getAccount();
|
||||||
$account->rules_agreement_version = LATEST_RULES_VERSION;
|
$account->rules_agreement_version = LATEST_RULES_VERSION;
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace api\modules\accounts\models;
|
namespace api\modules\accounts\models;
|
||||||
|
|
||||||
use api\aop\annotations\CollectModelMetrics;
|
|
||||||
use api\validators\EmailActivationKeyValidator;
|
use api\validators\EmailActivationKeyValidator;
|
||||||
use common\models\EmailActivation;
|
use common\models\EmailActivation;
|
||||||
use Webmozart\Assert\Assert;
|
use Webmozart\Assert\Assert;
|
||||||
@@ -17,9 +16,6 @@ class ChangeEmailForm extends AccountActionForm {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @CollectModelMetrics(prefix="accounts.changeEmail")
|
|
||||||
*/
|
|
||||||
public function performAction(): bool {
|
public function performAction(): bool {
|
||||||
if (!$this->validate()) {
|
if (!$this->validate()) {
|
||||||
return false;
|
return false;
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace api\modules\accounts\models;
|
namespace api\modules\accounts\models;
|
||||||
|
|
||||||
use api\aop\annotations\CollectModelMetrics;
|
|
||||||
use common\validators\LanguageValidator;
|
use common\validators\LanguageValidator;
|
||||||
use Webmozart\Assert\Assert;
|
use Webmozart\Assert\Assert;
|
||||||
|
|
||||||
@@ -16,9 +15,6 @@ class ChangeLanguageForm extends AccountActionForm {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @CollectModelMetrics(prefix="accounts.switchLanguage")
|
|
||||||
*/
|
|
||||||
public function performAction(): bool {
|
public function performAction(): bool {
|
||||||
if (!$this->validate()) {
|
if (!$this->validate()) {
|
||||||
return false;
|
return false;
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace api\modules\accounts\models;
|
namespace api\modules\accounts\models;
|
||||||
|
|
||||||
use api\aop\annotations\CollectModelMetrics;
|
|
||||||
use api\components\User\Component;
|
use api\components\User\Component;
|
||||||
use api\validators\PasswordRequiredValidator;
|
use api\validators\PasswordRequiredValidator;
|
||||||
use common\helpers\Error as E;
|
use common\helpers\Error as E;
|
||||||
@@ -44,9 +43,6 @@ class ChangePasswordForm extends AccountActionForm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @CollectModelMetrics(prefix="accounts.changePassword")
|
|
||||||
*/
|
|
||||||
public function performAction(): bool {
|
public function performAction(): bool {
|
||||||
if (!$this->validate()) {
|
if (!$this->validate()) {
|
||||||
return false;
|
return false;
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace api\modules\accounts\models;
|
namespace api\modules\accounts\models;
|
||||||
|
|
||||||
use api\aop\annotations\CollectModelMetrics;
|
|
||||||
use api\validators\PasswordRequiredValidator;
|
use api\validators\PasswordRequiredValidator;
|
||||||
use common\models\UsernameHistory;
|
use common\models\UsernameHistory;
|
||||||
use common\tasks\PullMojangUsername;
|
use common\tasks\PullMojangUsername;
|
||||||
@@ -24,9 +23,6 @@ class ChangeUsernameForm extends AccountActionForm {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @CollectModelMetrics(prefix="accounts.changeUsername")
|
|
||||||
*/
|
|
||||||
public function performAction(): bool {
|
public function performAction(): bool {
|
||||||
if (!$this->validate()) {
|
if (!$this->validate()) {
|
||||||
return false;
|
return false;
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace api\modules\accounts\models;
|
namespace api\modules\accounts\models;
|
||||||
|
|
||||||
use api\aop\annotations\CollectModelMetrics;
|
|
||||||
use api\validators\PasswordRequiredValidator;
|
use api\validators\PasswordRequiredValidator;
|
||||||
use api\validators\TotpValidator;
|
use api\validators\TotpValidator;
|
||||||
use common\helpers\Error as E;
|
use common\helpers\Error as E;
|
||||||
@@ -22,9 +21,6 @@ class DisableTwoFactorAuthForm extends AccountActionForm {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @CollectModelMetrics(prefix="accounts.disableTwoFactorAuth")
|
|
||||||
*/
|
|
||||||
public function performAction(): bool {
|
public function performAction(): bool {
|
||||||
if (!$this->validate()) {
|
if (!$this->validate()) {
|
||||||
return false;
|
return false;
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace api\modules\accounts\models;
|
namespace api\modules\accounts\models;
|
||||||
|
|
||||||
use api\aop\annotations\CollectModelMetrics;
|
|
||||||
use api\components\User\Component;
|
use api\components\User\Component;
|
||||||
use api\validators\PasswordRequiredValidator;
|
use api\validators\PasswordRequiredValidator;
|
||||||
use api\validators\TotpValidator;
|
use api\validators\TotpValidator;
|
||||||
@@ -24,9 +23,6 @@ class EnableTwoFactorAuthForm extends AccountActionForm {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @CollectModelMetrics(prefix="accounts.enableTwoFactorAuth")
|
|
||||||
*/
|
|
||||||
public function performAction(): bool {
|
public function performAction(): bool {
|
||||||
if (!$this->validate()) {
|
if (!$this->validate()) {
|
||||||
return false;
|
return false;
|
||||||
|
@@ -3,7 +3,6 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace api\modules\accounts\models;
|
namespace api\modules\accounts\models;
|
||||||
|
|
||||||
use api\aop\annotations\CollectModelMetrics;
|
|
||||||
use api\validators\PasswordRequiredValidator;
|
use api\validators\PasswordRequiredValidator;
|
||||||
use common\helpers\Error as E;
|
use common\helpers\Error as E;
|
||||||
use common\models\confirmations\CurrentEmailConfirmation;
|
use common\models\confirmations\CurrentEmailConfirmation;
|
||||||
@@ -37,9 +36,6 @@ class SendEmailVerificationForm extends AccountActionForm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @CollectModelMetrics(prefix="accounts.sendEmailVerification")
|
|
||||||
*/
|
|
||||||
public function performAction(): bool {
|
public function performAction(): bool {
|
||||||
if (!$this->validate()) {
|
if (!$this->validate()) {
|
||||||
return false;
|
return false;
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace api\modules\accounts\models;
|
namespace api\modules\accounts\models;
|
||||||
|
|
||||||
use api\aop\annotations\CollectModelMetrics;
|
|
||||||
use api\validators\EmailActivationKeyValidator;
|
use api\validators\EmailActivationKeyValidator;
|
||||||
use common\models\confirmations\NewEmailConfirmation;
|
use common\models\confirmations\NewEmailConfirmation;
|
||||||
use common\models\EmailActivation;
|
use common\models\EmailActivation;
|
||||||
@@ -23,9 +22,6 @@ class SendNewEmailVerificationForm extends AccountActionForm {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @CollectModelMetrics(prefix="accounts.sendNewEmailVerification")
|
|
||||||
*/
|
|
||||||
public function performAction(): bool {
|
public function performAction(): bool {
|
||||||
if (!$this->validate()) {
|
if (!$this->validate()) {
|
||||||
return false;
|
return false;
|
||||||
|
@@ -30,7 +30,6 @@
|
|||||||
"domnikl/statsd": "^3.0.0",
|
"domnikl/statsd": "^3.0.0",
|
||||||
"ely/mojang-api": "^0.2.0",
|
"ely/mojang-api": "^0.2.0",
|
||||||
"ely/yii2-tempmail-validator": "^2.0",
|
"ely/yii2-tempmail-validator": "^2.0",
|
||||||
"goaop/framework": "^2.2.0",
|
|
||||||
"guzzlehttp/guzzle": "^6|^7",
|
"guzzlehttp/guzzle": "^6|^7",
|
||||||
"lcobucci/jwt": "^3.3",
|
"lcobucci/jwt": "^3.3",
|
||||||
"league/oauth2-server": "dev-adaptation",
|
"league/oauth2-server": "dev-adaptation",
|
||||||
|
554
composer.lock
generated
554
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": "d028154ab9da3048a1ce9dc51b578149",
|
"content-hash": "3885d09d6c24355b0c314fc3259d185b",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "bacon/bacon-qr-code",
|
"name": "bacon/bacon-qr-code",
|
||||||
@@ -331,157 +331,6 @@
|
|||||||
],
|
],
|
||||||
"time": "2018-07-24T23:27:56+00:00"
|
"time": "2018-07-24T23:27:56+00:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "doctrine/annotations",
|
|
||||||
"version": "1.10.3",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/doctrine/annotations.git",
|
|
||||||
"reference": "5db60a4969eba0e0c197a19c077780aadbc43c5d"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/doctrine/annotations/zipball/5db60a4969eba0e0c197a19c077780aadbc43c5d",
|
|
||||||
"reference": "5db60a4969eba0e0c197a19c077780aadbc43c5d",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"doctrine/lexer": "1.*",
|
|
||||||
"ext-tokenizer": "*",
|
|
||||||
"php": "^7.1 || ^8.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"doctrine/cache": "1.*",
|
|
||||||
"phpunit/phpunit": "^7.5"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "1.9.x-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Guilherme Blanco",
|
|
||||||
"email": "guilhermeblanco@gmail.com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Roman Borschel",
|
|
||||||
"email": "roman@code-factory.org"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Benjamin Eberlei",
|
|
||||||
"email": "kontakt@beberlei.de"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Jonathan Wage",
|
|
||||||
"email": "jonwage@gmail.com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Johannes Schmitt",
|
|
||||||
"email": "schmittjoh@gmail.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Docblock Annotations Parser",
|
|
||||||
"homepage": "http://www.doctrine-project.org",
|
|
||||||
"keywords": [
|
|
||||||
"annotations",
|
|
||||||
"docblock",
|
|
||||||
"parser"
|
|
||||||
],
|
|
||||||
"time": "2020-05-25T17:24:27+00:00"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "doctrine/cache",
|
|
||||||
"version": "1.10.1",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/doctrine/cache.git",
|
|
||||||
"reference": "35a4a70cd94e09e2259dfae7488afc6b474ecbd3"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/doctrine/cache/zipball/35a4a70cd94e09e2259dfae7488afc6b474ecbd3",
|
|
||||||
"reference": "35a4a70cd94e09e2259dfae7488afc6b474ecbd3",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": "~7.1 || ^8.0"
|
|
||||||
},
|
|
||||||
"conflict": {
|
|
||||||
"doctrine/common": ">2.2,<2.4"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"alcaeus/mongo-php-adapter": "^1.1",
|
|
||||||
"doctrine/coding-standard": "^6.0",
|
|
||||||
"mongodb/mongodb": "^1.1",
|
|
||||||
"phpunit/phpunit": "^7.0",
|
|
||||||
"predis/predis": "~1.0"
|
|
||||||
},
|
|
||||||
"suggest": {
|
|
||||||
"alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "1.9.x-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Guilherme Blanco",
|
|
||||||
"email": "guilhermeblanco@gmail.com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Roman Borschel",
|
|
||||||
"email": "roman@code-factory.org"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Benjamin Eberlei",
|
|
||||||
"email": "kontakt@beberlei.de"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Jonathan Wage",
|
|
||||||
"email": "jonwage@gmail.com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Johannes Schmitt",
|
|
||||||
"email": "schmittjoh@gmail.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.",
|
|
||||||
"homepage": "https://www.doctrine-project.org/projects/cache.html",
|
|
||||||
"keywords": [
|
|
||||||
"abstraction",
|
|
||||||
"apcu",
|
|
||||||
"cache",
|
|
||||||
"caching",
|
|
||||||
"couchdb",
|
|
||||||
"memcached",
|
|
||||||
"php",
|
|
||||||
"redis",
|
|
||||||
"xcache"
|
|
||||||
],
|
|
||||||
"time": "2020-05-27T16:24:54+00:00"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "doctrine/lexer",
|
"name": "doctrine/lexer",
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
@@ -794,129 +643,6 @@
|
|||||||
],
|
],
|
||||||
"time": "2019-10-28T03:44:26+00:00"
|
"time": "2019-10-28T03:44:26+00:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "goaop/framework",
|
|
||||||
"version": "2.3.4",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/goaop/framework.git",
|
|
||||||
"reference": "f980f249c55637acba0d5fdcfd2b5182c419f3d1"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/goaop/framework/zipball/f980f249c55637acba0d5fdcfd2b5182c419f3d1",
|
|
||||||
"reference": "f980f249c55637acba0d5fdcfd2b5182c419f3d1",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"doctrine/annotations": "^1.2.3",
|
|
||||||
"doctrine/cache": "^1.5",
|
|
||||||
"goaop/parser-reflection": "~2.0",
|
|
||||||
"jakubledl/dissect": "~1.0",
|
|
||||||
"php": "~7.0",
|
|
||||||
"symfony/finder": "^3.4|^4.2|^5.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"adlawson/vfs": "^0.12",
|
|
||||||
"doctrine/orm": "^2.5",
|
|
||||||
"phpunit/phpunit": "^5.7",
|
|
||||||
"symfony/console": "^2.7|^3.0",
|
|
||||||
"symfony/filesystem": "^3.3",
|
|
||||||
"symfony/process": "^3.3",
|
|
||||||
"webmozart/glob": "^4.1"
|
|
||||||
},
|
|
||||||
"suggest": {
|
|
||||||
"symfony/console": "Enables the usage of the command-line tool."
|
|
||||||
},
|
|
||||||
"bin": [
|
|
||||||
"bin/aspect"
|
|
||||||
],
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "2.0-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Go\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Lisachenko Alexander",
|
|
||||||
"homepage": "https://github.com/lisachenko"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Framework for aspect-oriented programming in PHP.",
|
|
||||||
"homepage": "http://go.aopphp.com/",
|
|
||||||
"keywords": [
|
|
||||||
"aop",
|
|
||||||
"aspect",
|
|
||||||
"library",
|
|
||||||
"php"
|
|
||||||
],
|
|
||||||
"time": "2020-04-06T09:46:21+00:00"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "goaop/parser-reflection",
|
|
||||||
"version": "2.1.3",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/goaop/parser-reflection.git",
|
|
||||||
"reference": "2e837e150e15d38f7004b0dbcd0af4abe034c9e2"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/goaop/parser-reflection/zipball/2e837e150e15d38f7004b0dbcd0af4abe034c9e2",
|
|
||||||
"reference": "2e837e150e15d38f7004b0dbcd0af4abe034c9e2",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"nikic/php-parser": "^4.0 <4.7.0",
|
|
||||||
"php": ">=7.1"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"phpunit/phpunit": "~4.0"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "3.x-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Go\\ParserReflection\\": "src"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"src/bootstrap.php"
|
|
||||||
],
|
|
||||||
"exclude-from-classmap": [
|
|
||||||
"/tests/"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Alexander Lisachenko",
|
|
||||||
"email": "lisachenko.it@gmail.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Provides reflection information, based on raw source",
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/goaop/parser-reflection/issues",
|
|
||||||
"source": "https://github.com/goaop/parser-reflection/tree/2.x"
|
|
||||||
},
|
|
||||||
"time": "2020-08-13T21:02:42+00:00"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "guzzlehttp/guzzle",
|
"name": "guzzlehttp/guzzle",
|
||||||
"version": "7.2.0",
|
"version": "7.2.0",
|
||||||
@@ -1149,61 +875,6 @@
|
|||||||
},
|
},
|
||||||
"time": "2020-09-30T07:37:11+00:00"
|
"time": "2020-09-30T07:37:11+00:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "jakubledl/dissect",
|
|
||||||
"version": "v1.0.1",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/jakubledl/dissect.git",
|
|
||||||
"reference": "d3a391de31e45a247e95cef6cf58a91c05af67c4"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/jakubledl/dissect/zipball/d3a391de31e45a247e95cef6cf58a91c05af67c4",
|
|
||||||
"reference": "d3a391de31e45a247e95cef6cf58a91c05af67c4",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=5.3.3"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"symfony/console": "~2.1"
|
|
||||||
},
|
|
||||||
"suggest": {
|
|
||||||
"symfony/console": "for the command-line tool"
|
|
||||||
},
|
|
||||||
"bin": [
|
|
||||||
"bin/dissect.php",
|
|
||||||
"bin/dissect"
|
|
||||||
],
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"psr-0": {
|
|
||||||
"Dissect": [
|
|
||||||
"src/"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"unlicense"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Jakub Lédl",
|
|
||||||
"email": "jakubledl@gmail.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Lexing and parsing in pure PHP",
|
|
||||||
"homepage": "https://github.com/jakubledl/dissect",
|
|
||||||
"keywords": [
|
|
||||||
"ast",
|
|
||||||
"lexing",
|
|
||||||
"parser",
|
|
||||||
"parsing"
|
|
||||||
],
|
|
||||||
"time": "2013-01-29T21:29:14+00:00"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "lcobucci/jwt",
|
"name": "lcobucci/jwt",
|
||||||
"version": "3.3.2",
|
"version": "3.3.2",
|
||||||
@@ -1541,62 +1212,6 @@
|
|||||||
],
|
],
|
||||||
"time": "2021-02-11T18:30:17+00:00"
|
"time": "2021-02-11T18:30:17+00:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "nikic/php-parser",
|
|
||||||
"version": "v4.6.0",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/nikic/PHP-Parser.git",
|
|
||||||
"reference": "c346bbfafe2ff60680258b631afb730d186ed864"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/c346bbfafe2ff60680258b631afb730d186ed864",
|
|
||||||
"reference": "c346bbfafe2ff60680258b631afb730d186ed864",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"ext-tokenizer": "*",
|
|
||||||
"php": ">=7.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"ircmaxell/php-yacc": "0.0.5",
|
|
||||||
"phpunit/phpunit": "^6.5 || ^7.0 || ^8.0"
|
|
||||||
},
|
|
||||||
"bin": [
|
|
||||||
"bin/php-parse"
|
|
||||||
],
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "4.3-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"PhpParser\\": "lib/PhpParser"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"BSD-3-Clause"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Nikita Popov"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "A PHP parser written in PHP",
|
|
||||||
"keywords": [
|
|
||||||
"parser",
|
|
||||||
"php"
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/nikic/PHP-Parser/issues",
|
|
||||||
"source": "https://github.com/nikic/PHP-Parser/tree/v4.6.0"
|
|
||||||
},
|
|
||||||
"time": "2020-07-02T17:12:47+00:00"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "paragonie/constant_time_encoding",
|
"name": "paragonie/constant_time_encoding",
|
||||||
"version": "v2.4.0",
|
"version": "v2.4.0",
|
||||||
@@ -2225,55 +1840,6 @@
|
|||||||
],
|
],
|
||||||
"time": "2019-11-12T09:31:26+00:00"
|
"time": "2019-11-12T09:31:26+00:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "symfony/finder",
|
|
||||||
"version": "v5.1.0",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/symfony/finder.git",
|
|
||||||
"reference": "4298870062bfc667cb78d2b379be4bf5dec5f187"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/symfony/finder/zipball/4298870062bfc667cb78d2b379be4bf5dec5f187",
|
|
||||||
"reference": "4298870062bfc667cb78d2b379be4bf5dec5f187",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=7.2.5"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "5.1-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Symfony\\Component\\Finder\\": ""
|
|
||||||
},
|
|
||||||
"exclude-from-classmap": [
|
|
||||||
"/Tests/"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Fabien Potencier",
|
|
||||||
"email": "fabien@symfony.com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Symfony Community",
|
|
||||||
"homepage": "https://symfony.com/contributors"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Symfony Finder Component",
|
|
||||||
"homepage": "https://symfony.com",
|
|
||||||
"time": "2020-05-20T17:43:50+00:00"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-php80",
|
"name": "symfony/polyfill-php80",
|
||||||
"version": "v1.22.1",
|
"version": "v1.22.1",
|
||||||
@@ -3749,6 +3315,75 @@
|
|||||||
},
|
},
|
||||||
"time": "2020-09-30T17:56:20+00:00"
|
"time": "2020-09-30T17:56:20+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "doctrine/annotations",
|
||||||
|
"version": "1.10.3",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/doctrine/annotations.git",
|
||||||
|
"reference": "5db60a4969eba0e0c197a19c077780aadbc43c5d"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/doctrine/annotations/zipball/5db60a4969eba0e0c197a19c077780aadbc43c5d",
|
||||||
|
"reference": "5db60a4969eba0e0c197a19c077780aadbc43c5d",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"doctrine/lexer": "1.*",
|
||||||
|
"ext-tokenizer": "*",
|
||||||
|
"php": "^7.1 || ^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"doctrine/cache": "1.*",
|
||||||
|
"phpunit/phpunit": "^7.5"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.9.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Guilherme Blanco",
|
||||||
|
"email": "guilhermeblanco@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Roman Borschel",
|
||||||
|
"email": "roman@code-factory.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Benjamin Eberlei",
|
||||||
|
"email": "kontakt@beberlei.de"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jonathan Wage",
|
||||||
|
"email": "jonwage@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Johannes Schmitt",
|
||||||
|
"email": "schmittjoh@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Docblock Annotations Parser",
|
||||||
|
"homepage": "http://www.doctrine-project.org",
|
||||||
|
"keywords": [
|
||||||
|
"annotations",
|
||||||
|
"docblock",
|
||||||
|
"parser"
|
||||||
|
],
|
||||||
|
"time": "2020-05-25T17:24:27+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "doctrine/instantiator",
|
"name": "doctrine/instantiator",
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
@@ -6940,6 +6575,55 @@
|
|||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"time": "2020-05-30T20:35:19+00:00"
|
"time": "2020-05-30T20:35:19+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/finder",
|
||||||
|
"version": "v5.1.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/finder.git",
|
||||||
|
"reference": "4298870062bfc667cb78d2b379be4bf5dec5f187"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/finder/zipball/4298870062bfc667cb78d2b379be4bf5dec5f187",
|
||||||
|
"reference": "4298870062bfc667cb78d2b379be4bf5dec5f187",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.2.5"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "5.1-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Component\\Finder\\": ""
|
||||||
|
},
|
||||||
|
"exclude-from-classmap": [
|
||||||
|
"/Tests/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Fabien Potencier",
|
||||||
|
"email": "fabien@symfony.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Symfony Finder Component",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"time": "2020-05-20T17:43:50+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/options-resolver",
|
"name": "symfony/options-resolver",
|
||||||
"version": "v5.1.0",
|
"version": "v5.1.0",
|
||||||
|
Reference in New Issue
Block a user